# 👛SQL
全称 Structured Query Language,结构化查询语言。操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准
# 🏆SQL 通用语法
- SQL 语句可以单行或多行书写,以分号结尾。
- SQL 语句可以使用空格 / 缩进来增强语句的可读性。
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
- 注释:
- 单行注释:
-- 注释内容
或# 注释内容
- 多行注释:
/* 注释内容 */
- 单行注释:
# 🏆SQL 分类
SQL 语句,根据其功能,主要分为四类: DDL
、 DML
、 DQL
、 DCL
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象 (数据库,表,字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
# 🏆DDL
Data Definition Language,数据定义语言,用来定义数据库对象 (数据库,表,字段)
# 🎁数据库操作
查询所有数据库
show databases ;
查询当前数据库
select database() ;
创建数据库
create database [ if not exists ] 数据库名 [ default charset 字符集 ] [ collate 排序规则 ] ;
删除数据库
drop database [ if exists ] 数据库名 ;
切换数据库
use 数据库名 ;
# 🎁表操作
# 🏀表操作 - 查询创建
查询当前数据库所有表
show tables ;
查看指定表结构
desc 表名 ;
查询指定表的建表语句
show create table 表名 ;
创建表结构
CREATE TABLE 表名(
字段1 字段1类型 [ COMMENT 字段1注释 ],
字段2 字段2类型 [COMMENT 字段2注释 ],
字段3 字段3类型 [COMMENT 字段3注释 ],
......
字段n 字段n类型 [COMMENT 字段n注释 ]
) [ COMMENT 表注释 ] ;
注意: [...] 内为可选参数,最后一个字段后面没有逗号
# 🏀表操作 - 数据类型
MySQL 中的数据类型有很多,主要分为三类: 数值类型
、 字符串类型
、 日期时间类型
。
数值类型
类型 大小 有符号 (SIGNED) 范围 无符号 (UNSIGNED) 范围 描述 TINYINT 1 byte (-128, 127) (0, 255) 小整数值 SMALLINT 2 bytes (-32768, 32767) (0, 65535) 大整数值 MEDIUMINT 3 bytes (-8388608, 8388607) (0, 16777215) 大整数值 INT/INTEGER 4 bytes (-2147483648, 2147483647) (0, 4294967295) 大整数值 BIGINT 8 bytes (-2^63, 2^63-1) (0, 2^64-1) 极大整数值 FLOAT 4 bytes (-3.402823466 E+38, 3.402823466351 E+38) 0 和 (1.175494351 E-38, 3.402823466 E+38) 单精度浮点数值 DOUBLE 8 bytes (-1.7976931348623157 E+308, 1.7976931348623157 E+308) 0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308) 双精度浮点数值 DECIMAL 依赖于 M (精度) 和 D (标度) 的值 依赖于 M (精度) 和 D (标度) 的值 小数确定值 (精确到小数点后几位) 字符串类型
类型 | 大小 | 描述 |
---|---|---|
CHAR | 0-255 bytes | 定长字符串 (需要指定长度) |
VARCHAR | 0-65535 bytes | 变长字符串 (需要指定长度) |
TINYBLOB | 0-255 bytes | 不超过 255 个字符的二进制数据 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 |
TEXT | 0-65 535 bytes | 长文本数据 |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
日期时间类型
类型 大小 范围 格式 描述 DATE 3 1000-01-01 至 9999-12-31 YYYY-MM-DD 日期值 TIME 3 -838:59:59 至 838:59:59 HH:MM:SS 时间值或持续时间 YEAR 1 1901 至 2155 YYYY 年份值 DATETIME 8 1000-01-01 00:00:00 至 9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值 TIMESTAMP 4 1970-01-01 00:00:01 至 2038-01-19 03:14:07 YYYY-MM-DD HH:MM:SS 混合日期和时间值,时间戳
# 🏀表操作 - 修改
添加字段
ALTER TABLE 表名 ADD 字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];
修改数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型 (长度);
修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];
删除字段
ALTER TABLE 表名 DROP 字段名;
修改表名
ALTER TABLE 表名 RENAME TO 新表名;
# 🏀表操作 - 删除
删除表
DROP TABLE [ IF EXISTS ] 表名;
删除指定表,并重新创建表
TRUNCATE TABLE 表名;
注意:在删除表的时候,表中的全部数据也都会被删除。
# 🏆DML
DML 英文全称是 Data Manipulation Language (数据操作语言),用来对数据库中表的数据记录进行增、删、改操作。
- 添加数据(INSERT)
- 修改数据(UPDATE)
- 删除数据(DELETE)
# 🎁添加数据
给指定字段添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
给全部字段添加数据
INSERT INTO 表名 VALUES (值1, 值2, ...);
批量添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...) ;
INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...) ;
注意事项:
插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
字符串和日期型数据应该包含在引号中。
插入的数据大小,应该在字段的规定范围内。
# 🎁修改数据
UPDATE 表名 SET 字段名1 = 值1 , 字段名2 = 值2 , .... [ WHERE 条件 ] ; |
注意事项:
修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。
# 🎁删除数据
DELETE FROM 表名 [ WHERE 条件 ] ; |
注意事项:
- DELETE 语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。
- DELETE 语句不能删除某一个字段的值 (可以使用 UPDATE,将该字段值置为 NULL 即可)。
- 当进行删除全部数据操作时,datagrip 会提示我们,询问是否确认删除,我们直接点击 Execute 即可。
# 🏆DQL
DQL 英文全称是 Data Query Language (数据查询语言),数据查询语言,用来查询数据库中表的记录。
# 🎁基本语法
SELECT 字段列表 | |
FROM 表名列表 | |
WHERE 条件列表 | |
GROUP BY 分组字段列表 | |
HAVING 分组后条件列表 | |
ORDER BY 排序字段列表 | |
LIMIT 分页参数; |
- 基本查询(不带任何条件)
- 条件查询(WHERE)
- 聚合函数(count、max、min、avg、sum)
- 分组查询(group by)
- 排序查询(order by)
- 分页查询(limit)
# 🎁基础查询
查询多个字段
SELECT 字段1, 字段2, 字段3 ... FROM 表名 ;
SELECT * FROM 表名 ;
注意 : * 号代表查询所有字段,在实际开发中尽量少用(不直观、影响效率)。
字段设置别名
SELECT 字段1 [ AS 别名1 ] , 字段2 [ AS 别名2 ] ... FROM 表名;
SELECT 字段1 [ 别名1 ] , 字段2 [ 别名2 ] ... FROM 表名;
去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;
# 🎁条件查询
SELECT 字段列表 FROM 表名 WHERE 条件列表 ; |
常用的比较运算符如下:
比较运算符 | 功能 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
= | 等于 |
<> 或!= | 不等于 |
BETWEEN ... AND ... | 在某个范围之内(含最小、最大值) |
IN(...) | 在 in 之后的列表中的值,多选一 |
LIKE 占位符 | 模糊匹配 (_匹配单个字符,% 匹配任意个字符) |
IS NULL | 是 NULL |
常用的逻辑运算符如下:
逻辑运算符 | 功能 | ||
---|---|---|---|
AND 或 && | 并且(多个条件同时成立) | ||
OR 或 | 或者(多个条件任意一个成立) | ||
NOT 或! | 非,不是 |
# 🎁聚合函数
将一列数据作为一个整体,进行纵向计算 。
常见的聚合函数如下:
函数 | 功能 |
---|---|
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和 |
SELECT 聚合函数(字段列表) FROM 表名 ; |
注意 : NULL 值是不参与所有聚合函数运算的。
# 🎁分组查询
SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ]; |
where 与 having 区别执行时机不同:
- where 是分组之前进行过滤,不满足 where 条件,不参与分组;
- 而 having 是分组之后对结果进行过滤。判断条件不同:where 不能对聚合函数进行判断,而 having 可以。
注意事项:
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
- 执行顺序: where > 聚合函数 > having 。
- 支持多字段分组,具体语法为 : group by columnA,columnB
# 🎁排序查询
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 , 字段2 排序方式2 ; |
排序方式
- ASC : 升序 (默认值)
- DESC: 降序
注意事项:
- 如果是升序,可以不指定排序方式 ASC ;
- 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序;
# 🎁分页查询
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ; |
注意事项:
- 起始索引从 0 开始,起始索引 = (查询页码 - 1)* 每页显示记录数。
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL 中是 LIMIT。
- 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10。
# 🎁执行顺序
# 🏆DCL
DCL 英文全称是 Data Control Language (数据控制语言),用来管理数据库用户、控制数据库的访问权限。
# 🎁管理用户
查询用户
select * from mysql.user;
创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ;
删除用户
DROP USER '用户名'@'主机名' ;
注意事项:
- 在 MySQL 中需要通过
用户名@主机名
的方式,来唯一标识一个用户。 - 主机名可以使用
%
通配。 - 这类 SQL 开发人员操作的比较少,主要是 DBA( Database Administrator 数据库管理员)使用。
# 🎁权限控制
权限 | 说明 |
---|---|
ALL, ALL PRIVILEGES | 所有权限 |
SELECT | 查询数据 |
INSERT | 插入数据 |
UPDATE | 修改数据 |
DELETE | 删除数据 |
ALTER | 修改表 |
DROP | 删除数据库 / 表 / 视图 |
CREATE | 创建数据库 / 表 |
查询权限
SHOW GRANTS FOR '用户名'@'主机名' ;
授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
注意事项:
- 多个权限之间,使用
逗号
分隔 - 授权时, 数据库名和表名可以使用
*
进行通配,代表所有
。
# 👛函数
函数 是指一段可以直接被另一段程序调用的程序或代码。
MySQL 中的函数主要分为以下四类: 字符串函数
、 数值函数
、 日期函数
、 流程函数
。
# 🏆字符串函数
MySQL 中内置了很多字符串函数,常用的几个如下:
# 🏆数值函数
常见的数值函数如下:
# 🏆日期函数
常见的日期函数如下:
# 🏆流程函数
# 👛约束
# 🏆概述
概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
目的:保证数据库中数据的正确、有效性和完整性。
分类:
注意:约束是作用于表中字段上的,可以在创建表 / 修改表的时候添加约束
# 🏆外键约束
# 🎁介绍
外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。
# 🎁语法
添加外键
CREATE TABLE 表名(
字段名 数据类型,
...
[CONSTRAINT]
);
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名)
REFERENCES 主表 (主表列名) ;
删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
# 🎁 删除 / 更新行为
添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除 / 更新行为。具体的删除 / 更新行 为有以下几种:
具体语法为:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES | |
主表名 (主表字段名) ON UPDATE CASCADE ON DELETE CASCADE; |
在一般的业务系统中,不会修改一张表的主键值。
# 👛多表联查
# 🏆多表关系
- 一对多 (多对一)
- 多对多
- 一对一
# 🎁概述
多表查询就是指从多张表中查询数据。
# 🎁分类
连接查询
内连接:相当于查询 A、B 交集部分数据
外连接:
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
子查询
# 🏆内连接
内连接的语法分为两种: 隐式内连接
、 显式内连接
隐式内连接
SELECT 字段列表 FROM 表1 , 表2 WHERE 条件 ... ;
显式内连接
SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ... ;
表的别名:
①. tablea as 别名 1 , tableb as 别名 2 ; ②. tablea 别名 1 , tableb 别名 2 ;
注意事项:
一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字 段。
# 🏆外连接
外连接分为两种,分别是:左外连接 和 右外连接
左外连接
SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;
左外连接相当于查询表 1 (左表) 的所有数据,当然也包含表 1 和表 2 交集部分的数据。
右外连接
SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;
右外连接相当于查询表 2 (右表) 的所有数据,当然也包含表 1 和表 2 交集部分的数据。
注意事项: 左外连接和右外连接是可以相互替换的,只需要调整在连接查询时 SQL 中,表结构的先后顺 序就可以了。而我们在日常开发使用时,更偏向于左外连接。
# 🏆自连接
# 🎁自连接查询
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ; |
而对于自连接查询,可以是内连接查询,也可以是外连接查询。
注意事项:
在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。
# 🎁联合查询
对于 union 查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
SELECT 字段列表 FROM 表A ... | |
UNION [ ALL ] | |
SELECT 字段列表 FROM 表B ....; |
- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
- union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。
# 🏆子查询
# 🎁概述
概念
SQL 语句中嵌套 SELECT 语句,称为嵌套查询,又称子查询。
SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );
子查询外部的语句可以是 INSERT / UPDATE / DELETE / SELECT 的任何一个。
分类
根据子查询结果不同,分为:
标量子查询(子查询结果为单个值)
列子查询 (子查询结果为一列)
行子查询 (子查询结果为一行)
表子查询 (子查询结果为多行多列)
根据子查询位置,分为:
WHERE 之后
FROM 之后
SELECT 之后
# 🎁标量子查询
子查询返回的结果是 单个值
(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
常用的操作符: = <> > >= < <=
# 🎁列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
常用的操作符: IN
、 NOT IN
、 ANY
、 SOME
、 ALL
# 🎁行子查询
子查询返回的结果是 一行
(可以是 多列
),这种子查询称为行子查询。
常用的操作符: =
、 <>
、 IN
、 NOT IN
# 🎁表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询。
常用的操作符: IN
# 👛事务
# 🏆事务简介
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败
注意: 默认 MySQL 的事务是自动提交的,也就是说,当执行完一条 DML 语句时,MySQL 会立即隐 式的提交事务