首先,让我们来看看MySQL的整个组织框架
MySQL中有很多个数据库(database),每个数据库中都有很多张表(table),每张表中id,name,age则是用来描述数据的字段
那么,接下来,让我们来看看关于数据库,表,字段的各种操作是怎么样的
数据库
显示所有数据库
SHOW DATABASES
这个操作通常是我们打开MySQL之后的第一个指令
(当然,如果你非常清楚MySQL中有哪些数据库,那可以直接跳到第三步,或者你想创建一个新的数据库,则使用接下来的指令)
创建数据库
CREATE DATABASE database1
创建名为database1
的数据库
当我们再次查看所有数据库时,便发现已经有了我们刚才创建的数据库了
当我们试图创建已经存在的数据库时,MySQL会报出数据库已经存在的错误
但当我们上面语句中加入if not exists
,即
数据库不存在则创建,如果没有满足not exists
的条件,那么database1
就不会创建
因此,如果database1
已存在,则不会创建,也不会进行报错
create database if not exists database1
使用数据库
USE DATABASE database1
使用名为database1
的数据库
当我们试图使用不存在的数据库时MySQL则会报出不知名数据库'database2'的错误
删除数据库
DROP DATABASE database1
删除名为database1
的数据库
那如果数据库不存在我们还进行删除,则MySQL又会进行报错
其实处理方式就跟上面的创建数据库一样,我们加上if exists
条件就行
不同的是
创建的时候,我们的前置条件是if not exists
删除的时候,我们的前置条件是if exists
表
显示表
show tables
显示当前使用数据库中的所有表
这一步跟显示MySQL中所有数据库基本一致
创建表
- 指令
这个指令就相当于在数据库创建了下面这样的表
- 字段类型
这里面的int我们知道是整型,但varchar(20)呢,怎么没见过
看id int
我们大概能猜出是一个类型为int
,名字为id
的变量
但我们之前见过的计算机语言基本上命名变量时都是数据类型在前,在MySQL中,为什么数据类型要放在后面呢?
其实上面两个问题都属于历史遗留问题
(讲解一下这个历史遗留问题)
那么,接下来,让我们先来认识一下MySQL中都有哪些常用的数据类型,掌握了这个,我们才能轻松地创建出各种我们想要的表结构
数值类型
数据类型 | 大小 | 说明 |
---|---|---|
BIT[(M)] | M指定位数,默认为1 | 二进制数,M范围从1到64,存储数值范围从0到2^M-1 |
TINYINT | 1字节 | 类似Java中的Byte 类型 |
SMALLINT | 2字节 | 类似Java中的Short 类型 |
INT | 4字节 | 类似Java中的Integer 类型 |
BIGINT | 8字节 | 类似Java中的Long 类型 |
FLOAT(M, D) | 4字节 | 单精度, M指定长度, D指定小数位数, 类似Java中的Float 类型 |
DOULBE(M, D) | 8字节 | 同上, 类似Java中的Double 类型 |
DECIMAL(M, D) | M/D最大值+2 | 双精度, M指定长度, D表示小数点位数, 精确数值, 类似Java中的BigDecimal 类型 |
NUMERIC(M, D) | 同上 | 同上, 类似Java中的BigDecimal 类型 |
上面数据类型中较为常用的有BIT[(M)]
、INT
和DECIMAL
字符串类型
数据类型 | 大小 | 说明 |
---|---|---|
CHAR | ||
VARCHAR(SIZE) | 0-65535字节 | 可根据SIZE的大小确定字符串长度,类似Java中的String类 |
TEXT | 0-65535字节 | 长文本数据, 类似Java中的String类 |
MEDIUMTEXT | 0-16777215字节 | 中等长度文本数据, 类似Java中的String类 |
BLOB | 0-65535字节 | 二进制形式的长文本数据, 类似Java中的byte[]类型 |
这里面较为常有的有VARCHAR(SIZE)
和TEXT
类型
日期类型
数据类型 | 大小 | 说明 |
---|---|---|
DATATIME | 8字节 | 范围从1000到9999年,不会进行时区的检索及转换,类似Java中的java.util.Date、java.sql.Timestamp |
TIMESTAMP | 4字节 | 范围从1970到2038年,自动检索当前时区并进行转换,类似Java中的java.util.Date、java.sql.Timestamp |
- 查看表结构
当了解完SQL中所有数据类型之后,我们再回过头看啊可能我们前面创建好的test_table1
创建成功之后,只有一句短短的提示,我们即使知道已经创建出了如下图所示的表结构,可是我们应该怎么看到呢?
我们只需要使用desc test_table1
就可以查看到表的具体结构了,这里面的信息非常丰富,让我们来逐一了解
Field
也就是字段,即我们想要记录的数据的属性
Type
数据类型,各种数据类型我们已在前面详细介绍
Null
是否允许为空,想象一个场景,当我们有一张记录学生信息的表时,里面的字段有学号,性别,电话,获奖情况
那在录入学生信息的时候,如果学生没有获奖则获奖情况可以为空,而像性别,学号这样的数据则不能为空
YES的意思就是该信息允许为空,允许在插入数据的时候不插入该数据
Key
表示的是索引类型
在下面的约束中会有详细的介绍
Default
表示的是默认值
Extra
表示额外的说明
上面的Null
、Key
和Default
都可以通过下面的约束来进行设置
- 约束
当有一些信息,我们想要让它在没有填入的时候自动填入一个默认值,或者自动生成一个序号,或者不允许为空,或者增添一些额外的说明,那我们应该怎么做呢?
SQL中提供了约束来让我们实现以上的功能
约束类型 | 说明 |
---|---|
NOT NULL | 该字段不允许为空 |
UNIQUE | 该字段的数据只能为唯一的,不重复的 |
DEFAULT | 若该字段未插入数据,则自动设置默认值 |
PRIMARY KEY | 主键,表中每行的列的唯一标识 |
FOREIGN KEY | 外键,用于关联其他表的主键或唯一键 |
CHECK | 只能从给出的选项中进行选择 |
其实就是在创建表的时候,加入以下的约束语句,就可以达到我们上述的功能
NOT NULL
设置该约束之后,插入时便不能设为空
UNIQUE
设置该约束之后,就不能插入相同的数据,如插入两个学生的信息中名字不能相同
DEFAULT
设置该约束之后,如果没有插入数据,则会自动生成一个默认值,如没有插入性别的信息,则会自动将性别那一列的信息设置为保密
PRIMARY KEY
主键的作用在于将该字段设置为主要的标识
因此,设置为主键的字段本身就不能为空,我们也不必设置NOT NULL
约束了
而且一般主键都会搭配auto_increment
一起使用
FOREIGN KEY
外键用于关联其他表的主键或唯一键
CHECK
CHECK约束的意思就是只能在创建表时提供的选项中选择数据进行插入
但MySQL会忽略该约束,所以这个我们了解即可
- 表的设计
多对多
一对一
一对多
使用表(增删查改)
新增
- 单行数据 + 全列插入
下面语句的意思就是向test_table1表中插入(1, ‘张三’, '男', '成年')这组数据
这种插入方式是单行数据 + 全列插入,也就是插入的数据的顺序和个数都要跟一开始创建表时字段的顺序和个数一致,若我们在age
这个字段不想插入数据,则应该把上面语句改为
insert into test_table1 values(1, '张三', '男', NULL);
而不能仅仅写成
insert into test_table1 values(1, '张三', '男');
不然MySQL就会以为我们还没有输入完毕,因此也不会执行语句
这时候我们可以按ctrl + c
中断并且重新进行输入
那如果我们想要一次性插入多组数据呢?
那就要用到多行数据 + 指定列插入
- 多行数据 + 指定列插入
我们可以发现,不同的地方仅在于,在要插入数据的表后面说明一下字段的顺序和个数就行了,接着我们要插入的每一行数据都按照这个顺序和个数去插入就行了
例如,我们如果在插入时不想插入年龄,只需要在表后的字段说明中不写年龄就行了
查询
这里的查询查看的是数据,而前面的desc+表名
查看的是表的结构
一般我们会在插入之前看看表的结构,在插入之后使用查询查看插入的数据
- 全列查询
当我们要查看表中所有的数据时,就可以使用全列查询
这里的 select
是选中的意思,*
就是全部的意思
但是这个指令在我们工作中是比较危险的
因为这样会把表中的所有数据全都输出到屏幕上
而如果数据量大的话,可能就会造成系统崩溃
而且一般来说,我们是不需要查看所有的数据,只需要查看我们想要的那些数据,搭配下面的这些查询技巧,我们就可以轻松看到我们想看的数据了
- 指定列查询
当我们只想查看指定字段的时候,只需要把 *
改成想要的字段名就行了
- 查询字段为表达式
我们可以使用以下指令将我们想要的字段进行运算之后再打印出来
- 别名
我们在使用查询字段为表达式
的时候,可以使用别名将运算之后的结果重新起名
这里我们便是将运算之后的 id
起了别名为 newId
- 去重:DISTINCT
在查询性别的时候,我们发现查询的结果只有男
和女
两种,因此有许多重复的数据
当我们想去掉这些重复的数据时,只需要在查询的字段前面加上DISTINCT
关键字
当查询字段有多个时,如果加入 distinct
,则只会将所有字段都重复的数据进行去重
- 排序:ORDER BY
我们如果想要把我们查询到的数据按照特定字段去进行排序,则可以使用 order by
如,下面这个指令,就是按照 age
这个字段去排序我们查询到的数据
为什么 age
为 NULL
的数据会排在最前面呢?
因为 NULL
在排序时, 视为最小的数据, 且默认的顺序是升序
如果想改为升序, 只需要在 order by
后面的字段后再加上 desc
即可
- 条件查询:WHERE
在上面的查询中,我们会发现一个问题,就是虽说是查询,到无论是查询字段为表达式
、别名
、去重
、排序
,它们都只是在得到查询结果之后再进行一些操作
而通常我们在查询数据的时候,要求是比较精确的
比如要查询id
为1 - 100之间的人物信息
查询age
为成年的人物信息
查询name
里姓为张的人物信息
......
这些精确的查询要求,在MySQL中我们可以使用 WHERE
关键字来进行操作
先来看一下 WHERE
查询的运算符
运算符 | 说明 |
---|---|
>, >=, <, <=, =, != | 进行比较,其中NULL不安全,NULL=NULL的结果是NULL |
<=>, <> | 专用于比较 NULL,NULL<=>NULL的结果是TRUE |
BETWEEN x1 AND x2 | 匹配[x1, x2]范围内的所有数据 |
IN(option1, option2, option3, ...) | 匹配任意option中的一个 |
IS NULL | 匹配所有值为NULL的数据 |
IS NOT NULL | 匹配所有值不为NULL的数据 |
LIKE | 模糊匹配, % 表示任意多个(包括0个)任意字符, _ 表示任意一个字符 |
AND | 所有条件均为TRUE, 结果才为TRUE |
OR | 任意一个条件为TRUE, 结果就为TRUE |
NOT | 条件为TRUE, 结果为FALSE |
接下来我们通过一些案例来认识一下这些运算符怎么使用
首先我们创建这样的一张表来记录学生的信息
接着
查找所有英语成绩低于五十的学生
查找所有数学成绩在[70, 90]区间的学生
查找所有数学成绩为79, 78, 60的学生
查找所有数学成绩高于60且语文成绩低于60的学生
查找所有数学成绩高于60或语文成绩低于60的学生
当我们再插入孙悟空的成绩之后
查找所有姓孙的同学
- 分页查询:LIMIT
如果数据量太大的时候,我们只想要前几位数据或者后几位数据那我们就可以使用分页查询
查找总分前三的同学
limit 3
表示之查找三个数据
查找总分第四到第六的同学
offset 3
表示从总分第4(下标0表示第1,则3表示第4)的数据开始查找
- 聚合查询
聚合函数
GROUP BY子句
HAVING
- 联合查询
内连接
外连接
自连接
子查询
合并查询
修改
UPDATE 表名 SET 数据 = 值 查询条件
在查询条件部分,我们就可以运用前面的WHERE
,ORDER BY
,LIMIT
等来帮助我们精确找到想要修改的数据
将孙悟空的英语成绩修改为80
将倒数第三名的同学数学成绩加20
删除
DELETE FROM 表名 查询条件
删除孙悟空的成绩
同样的,我们可以先通过前面的查询条件来精确找到我们想删除的数据
删除表
删除表的操作和删除数据库的操作基本没有什么不同,这里就不做过多讲解
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。