SQL (Structured Query Language) 是用于管理和操作关系数据库的标准化编程语言。它允许用户执行各种操作,如查询、更新、插入和删除数据,以及管理数据库结构和权限。
SQL 分类:
DDL
数据定义语言,用来定义数据库对象(数据库、表、字段)DML
数据操作语言,用来对数据库表中的数据进行增删改DQL
数据查询语言,用来查询数据库中的记录DCL
数据控制语言,用来创建数据库用户、控住数据库的访问权限
# DDL - 数据库操作
查询:查询所有数据库 SHOW DATABASES
; 查询当前数据库 SELECT DATABASE()
;
创建: CREATE DATABASE [IF NOT EXISTS]
数据库名 【DEFAULT CHARSET字符集】``【COLLATE排序规则】
;
删除: DROP DATABASE【IF EXISTS】
数据库名;
使用: USE
数据库名;
DDL - 表操作 - 查询
查询当前数据库所有表 : SHOW TABLES
;
查询表结构: DESC
表名;
查询指定表的建表语句: SHOW CREATE TABLE
表名;
DDL - 表操作 - 创建
CREATE TABLE 表名( | |
字段1 字段1类型 COMMENT 字段1注释, | |
字段2 字段2类型 COMMENT 字段2注释, | |
字段3 字段3类型 COMMENT 字段3注释, | |
...... | |
字段n 字段n类型 COMMENT 字段n注释 | |
) COMMENT 表注释; ## 注意:【...】为可选参数,最后一个字段后面没有逗号 |
DDL - 表操作 - 数值类型
MySQL 中的数据类型很多,主要分为三类:数值类型、字符串类型、日期时间类型。
- 数值类型:
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT |
1 字节 | ±(2^7)-1 | 0~255 | 小整数值 |
SMALLINT |
2 字节 | ±(2^15)-1 | 0~65 535 | 大整数值 |
MEDIUMINT |
3 字节 | ±(2^23)-1 | 0~16 777 215 | 大整数值 |
INT或INTEGER |
4 字节 | ±(2^31)-1 | 0~4 294 967 295 | 大整数值 |
BIGINT |
8 字节 | ±(2^63)-1 | 0~18 446 744 073 709 551 615 | 极大整数值 |
FLOAT |
4 字节 | ±(1.175494351E-38) | ±(3.402823466E+38) | 单精度浮点数值 |
DOUBLE |
8 字节 | ±(2.2250738585072014E-308) | ±(1.7976931348623157E+308) | 双精度浮点数值 |
- 字符串类型:
类型 | 大小 | 用途 |
---|---|---|
CHAR |
0~255 字节 | 定长字符串 |
VARCHAR |
0~65535 字节 | 变长字符串 |
TINYBLOB |
0~255 字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT |
0~255 字节 | 短文本字符串 |
BLOB |
0~65 535 字节 | 二进制形式的长文本数据 |
TEXT |
0~65 535 字节 | 长文本数据 |
- 日期时间类型:
类型 | 大小(字节) | 范围 | 格式 | 用途 |
---|---|---|---|---|
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 结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038 年 1 月 19 日 凌晨 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
DDL - 表操作 - 修改
- 添加字段:
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 (数据操作语言),用来对数据库中的数据记录进行增删改操作。
DML - 添加数据:
- 给制定字段添加数据:
INSERT INTO
表名 (字段名 1,字段名 2,…)VALUES
(值 1,值 2,…); - 给全部字段添加数据:
INSERT INTO
表名VALUES
(值 1,值 2,…); - 批量添加数据:
INSERT INTO
表名(字段名 1,字段名 2,…)VALUES
(值 1,值 2,…),(值 1,值 2,…);
INSERT INTO
表名(值 1,值 2,…),(值 1,值 2,…),(值 1,值 2,…); - DML - 修改数据:
UPDATE
表名SET
字段名1 = 值1
,字段名2 = 值2
,…【WHERE 条件】; - DML - 删除数据:
DELETE FROM
表名【WHERE 条件】
# DQL - 介绍
DQL 英文全称是 Data Query Language (数据查询语言),数据查询语言,用于查询数据库中表的记录。查询关键字:SELECT
DQL - 基本查询:
- 查询多个字段:
SELECT
字段,字段 2,字段 3 …FROM
表名;
SELECT
*FROM
表名; - 设置别名:
SELECT
字段 1【AS
别名】,字段 2【AS
别名】 …FROM
表名; - 去除重复记录:
SELECT DISTINCT
字段列表FROM
表名; - DQL - 条件查询
- 语法:
SELECT
字段列表FROM
表名WHERE
条件列表; - 条件:
比较运算符:
- 语法:
比较运算符 | 功能 |
---|---|
> |
大于 |
>= |
大于等于 |
= |
等于 |
<> 或 != |
不等于 |
BETWEEN…AND |
在某个范围之内(含最小、最大值) |
IN(…) |
在 IN 之后的列表中的值,多选一 |
LIKE 占位符 |
模糊匹配(… 匹配单个字符,% 匹配热议字符) |
IS NULL |
是 NULL |
逻辑运算符:
逻辑运算符 | 功能 |
---|---|
AND 或 && |
并且(多个条件同时成立) |
OR 或 || |
或者(多个条件任意一个成立) |
NOT 或! |
非,不是 |
- DQL- 聚合函数
- 介绍:将一列数据作为一个整体,进行纵向计算。
- 常见聚合函数:
函数 | 功能 |
---|---|
COUNT |
统计数量 |
MAX |
最大值 |
MIN |
最下值 |
AVG |
平均值 |
SUM |
求和 |
- 语法:
SELECT
聚合函数(字段列表)FROM
表名;
- DQL - 分组查询
- 语法
SELECT
字段列表FROM
表名【WHERE 条件】GROUP BY
分组字段名【HAVING 分组后过滤条件】; where
与having
区别:- 执行时机不同: where 是分组之前进行过滤,不满足 where 条件,不参与分组;而 having 是分组之后对结果进行过滤;
- 判断条件不同: where 不能对聚类函数进行判断,而 having 可以。
【注意】
执行顺序:where > 聚合函数 > having
分组之后,查询的字段一般为聚合函数和分组字段,那其他字段无任何意义
- DQL - 排序查询
- 语法
SELECT
字段列表FROM
表名ORDER BY
字段 1 排序方式 1,字段 2 排序方式 2;
- 排序方式
ASC
(ascend):升序(默认)DESC
(descend):降序
【注意】 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。
- DQL - 分页查询
LIMIT
控制查询的起始位置和条目数:OFFSET
指定起始索引,LIMIT
指定查询条目数:
SELECT
字段列表FROM
表名LIMIT
查询条目数OFFSET
起始索引;
【注意】
- 起始索引从 0 开始,起始索引 = (查询页数 - 1)* 每页显示记录数
- 分页查询是数据库的方言,不同的数据库有不同的实现,
MYSQL
中是LIMIT
- 如果查询的是第一页数据,起始索引可以省略,直接简写为
limit 10
- 如果查询无结果,会返回空的结果集,不会报错。
# DCL - 介绍
DCL 英文全称 Data Control Language (数据控制语言),用来管理数据库用户、控制数据库的访问权限。
- DCL - 管理用户
- 查询用户:
USE
mysql;
SELECT
*FROM
user; - 创建用户
CREATE USER
‘用户名’@‘主机名’IDENTIFIED BY
‘密码’; - 修改用户密码
ALTER USER
‘用户名’@‘主机名’IDENTIFIED WITH
mysql_native_passwordBY
‘新密码’; - 删除用户
DROP USER
‘用户名’@‘主机名’;
【注意】 - 主机名可以使用 % 通配,示例:
'root'@'localhost'
表示只能在本地登录;'root'@'%'
表示可以在任意主机登录 - 这类 SQL 开发人员操作的比较少,主要是 DBA(Database Administrator 数据库管理员)使用。
- DCL - 权限控制
MySQL 中定义了很多种权限,但是常用的就一下几种:
权限 | 说明 |
---|---|
ALL 、 ALL PRIVILEGES |
所有权限 |
SELECT |
查询数据 |
INSERT |
插入数据 |
UPDATE |
修改数据 |
DELETE |
删除数据 |
ALTER |
修改表 |
DROP |
删除数据库 / 表 / 视图 |
CREATE |
创建数据库 / 表 |
- 查询权限
SHOW
GRANTS
FOR
‘用户名’@‘主机名’; - 授予权限
GRANT
权限列表ON
数据库名 表名TO
‘用户名’@‘主机名’; - 撤销权限
REVOKE
权限列表ON
数据库名 表名FROM
‘用户名’@‘主机名’;
表插入数据:
- 给指定字段添加数据:
INSERT INTO
表名 (字段名 1,字段名 2,…)VALUES
(值 1,值 2,…); - 给全部字段添加数据:
INSERT INTO
表名VALUES
(值 1,值 2,…); - 批量添加数据:
INSERT INTO
表名(字段名 1,字段名 2,…)VALUES
(值 1,值 2,…),(值 1,值 2,…);
INSERT INTO
表名(值 1,值 2,…),(值 1,值 2,…),(值 1,值 2,…);
表修改数据:
UPDATE
表名SET
字段名1 = 值1
,字段名2 = 值2
,…【WHERE 条件】;
表删除数据:
DELETE FROM
表名【WHERE 条件】
【注意】
- 多个权限之间,使用逗号分隔
- 授权书,数据库名和表名可以使用 * 进行通配,代表所有。
【函数】
一段可以直接被另一程序调用的程序或代码
字符串函数:MySQL 中内置了很多字符串函数,常用的几个如下:
函数 | 功能 |
---|---|
CONCAT(S1,S2,..Sn) |
字符串拼接,将 S1,S2,…Sn 拼接成一个字符穿 |
LOWER(str) |
将字符串 str 全部转为小写 |
UPPER(str) |
将字符串 str 全部转为大写 |
LPAD(str,n,pad) |
左填充,用字符串 pad 对 str 的左边进行填充,达到 n 个字符串长度 |
RPAD(str,n,pad) |
右填充,用字符串 pad 对 str 的右边进行填充,达到 n 个字符串长度 |
TRIM(str) |
去掉字符串头部和尾部的空格 |
SUBSTRING(str,start,len) |
返回从字符串 str 从 start 位置的 len 个长度的字符串 |
数值函数:
函数 | 功能 |
---|---|
CEIL(X) |
向上取整 |
FLOOR(X) |
向下取整 |
MOD(x,y) |
返回 x/y 的模 |
RAND() |
返回 0~1 内的随机数 |
ROUND(X,Y) |
求参数 x 的四舍五入的值,保留 y 位小数 |
日期函数:
函数 | 功能 |
---|---|
CURDATE() |
返回当前日期 |
CURTIME() |
返回当前时间 |
NOW() |
返回当前日期和时间 |
YEAR(date) |
获取制定 date 的年份 |
MONTH(date) |
获取指定 date 的月份 |
DAY(date) |
获取指定 date 的日期 |
DATE_ADD(date, INTERVAL expr type) |
返回日期 / 时间值加时间间隔 expr 后的时间 |
DATEDIFF(date1,date2) |
返回起始时间 date1 和结束 date2 之间天数 |
流程函数:
流程函数也是很常用的一类函数,可以在 SQL 语句中实现条件筛选,从而提高语句的效率。
函数 | 功能 |
---|---|
IF(value,t,f) |
如果 value 为 true, 则返回 t,否则返回 f |
IFNULL(value1,value2) |
如果 value1 不为空,返回 value1,否则返回 value2 |
CASE WHEN 【val1】 THEN 【res1】… ELSE 【dafault】 END |
如果 val1 为 true, 返回 res1,… 否则返回 default 默认值 |
CASE 【expr】 WHEN 【val1】 THEN 【res1】… ELSE 【default】 END |
如果 expr 的值等于 val1, 返回 res1,… 否则返回 default 默认值 |
约束
- 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据
- 目的:保证数据库中数据的正确、有效性和完整性
分类:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为 NULL | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识、要求非空且唯一 | PRIMARY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFCK |
检查约束(8.0.16 版本之后) | 保证字段满足某一个条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
【注意】:约束是作用于表中字段上的,可以在创建表 / 修改表的时候添加约束。
外键约束
- 概念:外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。
- 语法:
- 添加外键:
CREATE TABLE 表名(
字段名 数据类型,
…
【CONSTRAINT】【外键名称】FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名)
);
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);
- 删除外键:
ALTER TABLE
表名DROP
FPREIGN
KEY
外键名称; - 删除 / 更新行为:
行为 | 说明 |
---|---|
NO ACTION |
当在父表中删除 / 更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除 / 更新。(与 RESTRICT 一致) |
RESTRICT |
当父表中删除 / 更新记录时,首先检查记录是否有对应外键,如果有则不允许删除 / 更新。(与 NO ACTION 一致) |
CASCADE |
当父表中删除 / 更新记录时,首先检查记录是否有对应外键,如果有,则也删除 / 更新外键在子表中的记录。 |
SET NULL |
当父表中删除 / 更新记录时,首先检查记录是否有对应外键,如果有则设置子表中该外键值为 NULL(这就要求该外键允许取 NULL) |
SET DEFAULT |
父表有变更时,子表将外键列设置成一个默认的值(lnnodb 不支持) |
ALTER TABLE
表名 ADD CONSTRAINT
外键名称 FOREIGN KEY
(外键字段) REFERENCES
主表名
# 多表查询
多表关系
项目开发中,在进行数据库表格结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本分为三种: 一对多(多对一)、多对多、一对一。
- 一对多(多对一):
案例:部门与员工的关系
关系:一个部门对应多个员工,一个员工对应一个部门
实现:在多的一方(员工表)建立外键,指向一的一方(部门表)的主键 - 多对多:
案例:学生与课程的关系
关系:一个学生可以选修对门课程,一门课程也可以供多个学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键 - 一对一:
案例:用户与用户详情的关系
关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提高操作效率。
实现:在任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(UNIQUE)
多表查询概述:
概述:指从多张表中查询数据。
笛卡尔积:笛卡尔乘积是指在数学中,两个集合 A 集合和 B 集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)。
多表查询分类: - 连接查询:
- 内连接:相当于查询 A、B 交集部分数据
- 外连接:
- 左外连接:查询左表所有数据,以及两张表交集部分数据
- 右外连接:查询右表所有数据,以及两张表交集部分数据
- 自连接:当前表与自身的连接查询,自连接必须使用表别名
- 子查询:
- 连接查询 - 内连接(查询两表交集的部分)
- 内连接查询语法:
(A inner join B:AB两表值都存在)
- 隐式内连接:
- SELECT 字段列表 FROM 表 1,表 2 WHERE 条件…;
- 显示内连接:
- SELECT 字段列表 FROM 表 1【INNER】JOIN 表 2 ON 连接条件…;
- 隐式内连接:
- 连接查询 - 外连接:
(A 【outer】 join B:AB两表值可能存在null的情况)
A inner join B:
取交集
A left join B:
取 A 全部,B 没有对应的值,则为 null
A right join B:
取 B 全部,A 没有对应的值,则为 null
A full outer join B:
取并集,彼此没有对应的值为 null
- 外连接查询语法:
- 左外连接:
SELECT
字段列表FROM
表 1LEFT【OUTER】JOIN
表 2ON
条件…;
- 右外连接:
- SELECT 字段列表 FROM 表 1
RIGHT【OUTER】JOIN
表 2ON
条件…;
- SELECT 字段列表 FROM 表 1
- 左外连接:
- 连接查询 - 自连接:
- 自连接查询语法:
SELECT
字段列表FROM
表 A 别名 AJOIN
表 A 别名 BON
条件…;
- 自连接查询,可以是内连接查询,也可以是外连接查询。
- 联合查询 - union,union all
- 对于 union 查询,就是把多次查询结果联合起来,形成一个新的查询结果集
# 窗口函数
窗口函数又称为 OLAP 函数(Online Anallytical Processing,联机分析处理),可以对查询结果集中的每一行进行计算,并返回一个结果。窗口函数的返回值不依赖与查询中的其他行,只需要基于当前行通过 OVER 子句指定分析窗口即可。
窗口函数语法:
<窗口函数> OVER (PARTITION BY <用于分组的类名:列1, 列2...> ORDER BY <用于排序的列名>) |
其中:
PARTITION BY
:指定分组列,即先按照某个字段进行分组。ORDER BY
:指定排序的列,先按照某个字段进行排序。<窗口函数>
:要使用的聚合函数或者专门的窗口函数。
函数 | 功能 |
---|---|
RANK() OVER() |
排名,相同排名会占用名次,名次不连续 |
DENSE_RANK() OVER() |
排名,相同排名会占用名次,名次连续 |
ROW_NUMBER() OVER() |
排名,相同排名也会占用名次,名次不连续 |
FIRST_VALUE() OVER() |
取分组内排序后,截止到当前行,第一个值 |
# 子查询
子查询是指嵌入在其他 SQL 语句中的 SELECT 语句,也叫嵌套查询。子查询可以嵌套在 SQL 语句中的 WHERE
、 SELECT
、 FROM
或 HAVING
子句中。
子查询语句分类:
- 单行子查询:子查询结果为单行单列,操作符有:
=
、<>
、<
、<=
、>
、>=
。 - 多行子查询:子查询结果为多行单列或多行多列,操作符有:
IN
、ANY
、ALL
。