技术交流QQ群:1027579432,欢迎你的加入!
第一章 了解SQL
1.1 数据库基础
- 数据库:保存有组织的数据的容器(通常是一个文件或一组文件)。注意要与数据库软件DBMS(数据库管理系统)区别,数据库是通过DBMS创建和操纵的容器。数据库可以是保存在硬件设备上的文件,但也可以不是。很大程度上来说,数据库究竟是文件还是别的什么并不重要,因为你并不直接访问数据库,你使用的是DBMS,它替你访问数据库。
- 表:某种特定类型数据的结构化清单。关键点:存储在表中的数据是一种类型的数据或是一个清单。数据库中的每个表都有一个名字,用来标识自己。此名字是唯一的,标识数据库中没有其他表具有相同的名字。虽然相同的数据库中不能两次使用相同的表名,但是在不同的数据库中可以使用相同的表名。
- 模式:关于数据库和表的布局和特性的信息。
- 列:表由列组成的。列中存储着表中某部分的信息。列即表中的一个字段,所有表都是由一个或多个列组成的。数据库中每列都有相应的数据类型。数据类型定义列可以存储的数据种类。
- 数据类型:所容许的数据的类型。每个表的列都有相应的数据类型,它限制该列中存储的数据。数据类型限制可存储在列中的数据种类。
- 行:表中的数据是按行存储的,所保存的每个记录存储在自己的行内。如果将表看出一个网格,网格中的垂直的列是表的列,水平行位表行。行(也称为记录)即表中的一个记录。
- 主键/键码/码:一列(或者一组列),其值能够唯一区分表中每个行。唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示一个特定的行,没有主键,更新或删除表中特定行很困难,因为没有安全的方法保证只涉及相关的行。应该总是定义主键,虽然并不总是都需要主键,但大多数情况下应该保证创建的每个表具有一个主键,便于后序的操作。表中任何列都可以作为主键,只有满足下面的条件:
- 任意两行都不具有相同的主键值;
- 每个行都必须具有一个主键值(主键值不允许为NULL值);
- 注意:主键通常定义在表的一列上,但这不是必须的。也可以一起使用多个列作为主键。在使用多个列作为主键时,上面的条件必须应用到构成主键的所有列,所有列值的组合必须是唯一的(但是单个列的值可以不唯一)。
- 主键使用的最好习惯:
- 不更新主键列中的值;
- 不重用主键列中的值;
- 不在主键列中使用可能会更改的值;
1.2 什么是SQL
- SQL是结构化查询语言,是一种专门用来与数据库通信的语言。
- SQL语言的优点:
- SQL不是某个特定数据库供应商专有的语言,几乎所有重要的DBMS都支持SQL
- SQL简单易学
- SQL尽管看上去简单,但是实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作。
第二章 MySQL简介
2.1 什么是MySQL
- 数据的所有存储、检索、管理和处理实际上是由数据库软件---DBMS(数据库管理系统)完成的。MySQL是一种DBMS,即它是一种数据库软件。
- DBMS的分类:
- a.基于共享文件系统的DBMS;用于桌面用途,通常不用于高端或更关键的应用。
- b.基于客户机-服务器的DBMS;MySQL、Oracle、SQL Server等数据库是基于客户机-服务器的数据库,可以分为两个不同的部分。服务器部分负责所有数据的访问和处理的一个软件,这个软件运行在称为数据库服务器的计算机上。与数据文件打交道的只有服务器软件。关于数据、数据添加、删除、更新的所有请求都是由服务器软件完成的。这些请求或更改都是来自客户机软件的计算机。客户机是与用户大打交道的软件。
- 客户机和服务器软件可能安装在两台计算机或一台计算机上。不管它们是否在相同的计算机上,为了进行所有数据库交互,客户机软件都要与服务器软件进行通信。
- 命令是用;或\g结束的,就是说仅按Enter不执行命令;输入help或\h获得帮助;\q是退出
第三章 使用MySQL
1. 连接
- 为了连接到MySQL,需要下面的信息:
- 主机名(计算机名),如果连接到本地MySQL服务器,为localhost;
- 端口,如果使用默认端口3306之外的端口;
- 一个合法的用户名;
- 用户口令(如果需要的话);
2.选择数据库
- 在你能执行任意数据库操作前,需要选择一个数据库。可以使用use关键字。use语句并不返回任何结果,依赖于使用的客户机,显示某种形式的通知。例如,显示的Database changed消息是mysql命令行实用程序在数据库选择成功后显示的。必须先使用use打开数据库,才能读取其中的数据。
mysql> use dalao;
Database changed
- 关键字:作为MySQL语言组成部分的一个保留字,绝不要用关键字命名一个表或列!!!
- 数据库、表、列、用户、权限等的信息被存储在数据库和表中。不过,内部的表一般不直接访问,可以使用show命令来显示这些信息。show databases;返回可用数据库中的一个列表。包含在这个列表中的可能是MySQL内部使用的数据库(如,information_schema)。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dalao |
| demo_db |
| django |
| django_database |
| mysite |
| mysql |
| performance_schema |
| polls |
| runoob |
| spiders |
| students |
| sys |
+--------------------+
13 rows in set (0.00 sec)
- 为了获得一个数据库中的表的列表,使用show tables;此命令返回当前选择的数据库内可用表的列表,show也可以显示表的列,等价于desc 表名是一种show columns from 表名的一种快捷方式!。如下所示:
mysql> show tables;
+-----------------+
| Tables_in_dalao |
+-----------------+
| caiji |
| njust |
| tlu |
+-----------------+
3 rows in set (0.00 sec)
mysql> show columns from caiji;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| score | int(11) | YES | | NULL | |
| grade | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
5 rows in set (1.66 sec)
分析:show columns 要求给出一个表的名字,它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、键信息、默认值及其他信息(如 auto_increment)等。
mysql> desc caiji;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| score | int(11) | YES | | NULL | |
| grade | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
5 rows in set (0.05 sec)
- auto_increment(自动增量):某些表列需要唯一值。在每行添加到表中时,MySQL可以自动地为每个行分配下一个可用编号,不用在添加一行时收到分配唯一值(这样做就必须记住最后一次使用的值),这个功能就是所谓的自动增量。如果需要它就必须在用create语句创建表时把它作为表定义的组成部分。
- 所支持的其他show语句有:
- show status;用于显示广泛的服务器状态信息;
- show create database 数据库名;和 show create table 表名;分别用来显示创建特定数据库或表的MySQL语句;
- show grants;用来显示授权用户(所有用户或特定用户)的安全权限;
- show errors;和show warnings;用来显示服务器错误或警告消息;
- 忘记一条SQL指令用法时,使用help 指令名来进行帮助!!!!
- MySQL5支持一个新的INFORMATION_SCHEMA命令,可以用它来获得和过滤模式信息。information_schema这张数据表保存了MySQL服务器所有数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。用法:select * from INFORMATION_SCHEMA.TABLES;
第四章 检索数据
1.select语句
- 最常用的SQL语句就是select语句,它的用途是从一个表或多个表中检索信息。为了使用select检索表数据,必须至少给出两条信息(想选择什么、从什么地方选择)。
2.检索单个列
```
mysql> select name from caij
+--------+
| name |
+--------+
| Curry |
| Durant |
| James |
| Zion |
+--------+
4 rows in set (0.11 sec)
```
- 上面语句中利用select语句从caiji表中检索一个名为name的列。所需的列名在select关键字之后给出,from关键字指出从其中检索数据的表名。SQL语句不区分大小写,因此SELECT和select是相同的。一般,所有SQL关键字使用大写,而对所有列和表名使用小写,这样做使代码更易于阅读和调试;将SQL语句分成多行更易于阅读和调试。
3.检索多个列
- 要想从一个表中检索出多个列,使用相同的SELECT语句,唯一的不同是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。注意逗号一定要在列名之间加上,但最后一个列名后不加!!!
mysql>
mysql> SELECT id, name, age, grade
-> FROM caiji;
+------+--------+------+-------+
| id | name | age | grade |
+------+--------+------+-------+
| 1 | Curry | 31 | 09年 |
| 2 | Durant | 30 | 08年 |
| 3 | James | 34 | 03年 |
| 4 | Zion | 19 | 新秀 |
+------+--------+------+-------+
4 rows in set (0.00 sec)
4.检索所有列
5.检索不同的行
mysql> SELECT name
-> FROM caiji;
+--------+
| name |
+--------+
| Curry |
| Durant |
| James |
| Zion |
| Curry |
+--------+
5 rows in set (0.00 sec)
mysql> SELECT DISTINCT name
-> FROM caiji;
+--------+
| name |
+--------+
| Curry |
| Durant |
| James |
| Zion |
+--------+
4 rows in set (0.06 sec)
- 使用distinct关键字,表示只返回不同的值。注意distinct关键字放的位置,它必须放在列名的前面!不能部分使用DISTINCT distinct关键字应用于所有列而不仅仅是前置它的列。如果给出SELECT DISTINCT name, grade;除非指定的两个列都不同,否则所有行都将被检索出来。
6.限制结果
mysql> SELECT name
-> FROM caiji
-> LIMIT 1, 4;
+--------+
| name |
+--------+
| Durant |
| James |
| Zion |
| Curry |
+--------+
4 rows in set (0.00 sec)
7.使用完全限定的表名
第五章 排序检索数据
1.排序数据
- 下面的SQL语句返回某个数据库表的单个列,注意看到它的输出并没特定的顺序。
mysql> SELECT age
-> FROM njust;
+------+
| age |
+------+
| 12 |
| 15 |
| 14 |
| 13 |
| 12 |
+------+
5 rows in set (0.00 sec)
- 其实,检索出来的数据并不是以随机的顺序显示的。如果不使用排序语句,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表中的顺序,但是,如果数据后来进行过更新或删除,则此顺序将会受到MySQL重回收存储空间的影响。关系型数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
- 子句:SQL语句由子句组成,有些子句是必须的,有些子句则是可选择的。一个子句通常由一个关键字和所提供的数据组成。子句的例子有SELECT语句的FROM子句。为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。ORDER BY子句取一个列或多个列的名字,据此对输出进行排序。实例如下:
mysql> SELECT age
-> FROM njust
-> ORDER BY age;
+------+
| age |
+------+
| 12 |
| 12 |
| 13 |
| 14 |
| 15 |
+------+
5 rows in set (0.00 sec)
- 注意:通常ORDER BY子句中使用的列将是为显示所选择的列。但是,实际上并不一定非要这样,用非检索的列排序数据是完全合法的。如下所示:
mysql> SELECT name, age
-> FROM njust
-> ORDER BY address;
+------+------+
| name | age |
+------+------+
| 大雄 | 15 |
| 静香 | 14 |
| 小度 | 12 |
| 小明 | 12 |
| 胖虎 | 13 |
+------+------+
5 rows in set (0.06 sec)
2.按多个列排序
- 为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列那样做就可以)。在按多个列排序时,排序完全按所规定的顺序进行。也就是说,下面的例子中,当多个行具有相同的姓名name时,才会按照年龄age排序。如果姓名name列中所有的值都是唯一的,则不会按年龄age来排序。
mysql> SELECT name, age, sex
-> FROM njust
-> ORDER BY name, age; // 首先按姓名排序,然后再按年龄排序
+------+------+------+
| name | age | sex |
+------+------+------+
| 大雄 | 15 | 男 |
| 小度 | 12 | 男 |
| 小明 | 12 | 男 |
| 胖虎 | 13 | 男 |
| 静香 | 14 | 女 |
+------+------+------+
5 rows in set (0.00 sec)
3.指定排序方向
- 数据排序不限于升序排序(A到Z),这是默认的排序顺序。可以使用ORDER BY子句以降序(Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
mysql> SELECT name, age, sex
-> FROM njust
-> ORDER BY age DESC;
+------+------+------+
| name | age | sex |
+------+------+------+
| 大雄 | 15 | 男 |
| 静香 | 14 | 女 |
| 胖虎 | 13 | 男 |
| 小明 | 12 | 男 |
| 小度 | 12 | 男 |
+------+------+------+
5 rows in set (0.00 sec)
- 如果对多个列排序时,DESC关键字只应用在直接位于其前面的列名。例如下面的例子中,只对age列指定DESC,对name列不指定。因此age列以降序排序;而name列仍然按标准升序排序。如果想对多个列进行降序排序,必须对每个列指定DESC关键字。
mysql> SELECT name, age, sex
-> FROM njust
-> ORDER BY age DESC, name;
+------+------+------+
| name | age | sex |
+------+------+------+
| 大雄 | 15 | 男 |
| 静香 | 14 | 女 |
| 胖虎 | 13 | 男 |
| 小度 | 12 | 男 |
| 小明 | 12 | 男 |
+------+------+------+
5 rows in set (0.00 sec)
- 与DESC关键字相关的关键字是ASC,在升序排序时可以指定它。但实际上,ASC没有多大用处,因为升序是默认的。
- 使用ORDER BY和LIMIT的组合,能够找出一个列中的最大值或最小值,如下面的例子:
mysql> SELECT age
-> FROM njust
-> ORDER BY age DESC
-> LIMIT 1;
+------+
| age |
+------+
| 15 |
+------+
1 row in set (0.06 sec)
- 注意:ORDER BY子句的位置应该保证它位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY之后。
第六章 过滤数据
1.使用WHERE子句
2.WHERE子句操作符
2.1 检测单个值
- 检查WHERE name = "小明"语句,它返回name的值是“小明”的行。MySQL在执行匹配时默认不区分大小写,所以A与a相同的。
mysql> SELECT name, age
-> FROM njust
-> WHERE name = "小明"
+------+------+
| name | age |
+------+------+
| 小明 | 12 |
+------+------+
1 row in set (0.05 sec)
- 下面的例子是列出年龄age大于12的所有同学:
mysql> SELECT name, age
-> FROM njust
-> WHERE age > 12;
+------+------+
| name | age |
+------+------+
| 大雄 | 15 |
| 静香 | 14 |
| 胖虎 | 13 |
+------+------+
3 rows in set (0.00 sec)
2.2 不匹配检查
2.3范围值检查
4.空值检查
第七章 数据过滤
1.组合WHERE子句
- 上面一章中,所有的WHERE子句在过滤数据时使用的都是单一的条件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子句可以以两种方式使用:
- 操作符:用来连接或改变WHERE子句中的子句的关键字,也称为逻辑操作符。
1.1 AND操作符
1.2 OR操作符
- OR操作符与AND操作符不同,它表示MySQL检索匹配任一条件的行。如下面的例子:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE id = 1 OR id = 3;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | 小明 | 12 |
| 3 | 静香 | 14 |
+----+------+------+
2 rows in set (0.00 sec)
1.3 计算次序
- WHERE子句可以包含任意数量的AND和OR操作符。允许两者结合来进行复杂和高级的过滤。如下面的例子:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE id = 2 or id = 3 AND age < 12;
+----+------+------+
| id | name | age |
+----+------+------+
| 2 | 大雄 | 15 |
+----+------+------+
1 row in set (0.00 sec)
- 返回的行没有按照预期的进行过滤。SQL在处理OR操作符前,优先处理AND操作符。当SQL看到上述WHERE子句时,它理解为年龄age小于12的同学或者id = 2的同学,而不管其年龄是多少。换句话说,由于AND在计算次序中优先级更高,操作符被错误组合了。解决方法是使用圆括号明确地分组相应的操作符,如下所示:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE (id = 2 or id = 3) AND age < 12;
Empty set (0.00 sec)
- WHERE子句中使用圆括号,在任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它的确是你想要的东西也是如此。
2.IN操作符
- 圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都括在圆括号中。如下面的例子所示:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE id IN (1, 3)
-> ORDER BY name;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | 小明 | 12 |
| 3 | 静香 | 14 |
+----+------+------+
2 rows in set (0.00 sec)
- IN操作符完成与OR相同的功能,IN操作符一般比OR操作符执行的更快。IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。看下面的例子:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE id = 1 OR id = 3
-> ORDER BY name;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | 小明 | 12 |
| 3 | 静香 | 14 |
+----+------+------+
2 rows in set (0.00 sec)
3.NOT操作符
- WHERE子句中NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。MySQL支持使用NOT对IN、BETWEEN和EXISTS子句取反。如下面的例子:
mysql> SELECT id, name, age
-> FROM njust
-> WHERE id NOT IN (1,3)
-> ORDER BY name;
+----+------+------+
| id | name | age |
+----+------+------+
| 2 | 大雄 | 15 |
| 5 | 小度 | 12 |
| 4 | 胖虎 | 13 |
+----+------+------+
3 rows in set (0.00 sec)
第八章 用通配符进行过滤
1.LIKE操作符