SQL (Structured Query Language) 是用于管理和操作关系数据库的标准化编程语言。它允许用户执行各种操作,如查询、更新、插入和删除数据,以及管理数据库结构和权限。

SQL 分类:

  1. DDL 数据定义语言,用来定义数据库对象(数据库、表、字段)
  2. DML 数据操作语言,用来对数据库表中的数据进行增删改
  3. DQL 数据查询语言,用来查询数据库中的记录
  4. 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 - 表操作 - 修改

  1. 添加字段: ALTER TABLE 表名 ADD 字段名 类型(长度) 【COMMENT 注释】``【约束】 ;
  2. 修改数据类型: ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
  3. 修改字段名和字段类型: ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) 【COMMENT注释】``【约束】 ;
  4. 删除字段: ALTER TABLE 表名 DROP 字段名;
  5. 修改表名: ALTER TABLE 表名 RENAME TO 新表名;
  6. 删除表: DROP TABLE【IF EXISTS】 表名;
  7. 删除指定表,并重新创建该表: TRUNCATE TABLE 表名;

# DML - 介绍

DML 英文全称是 Data Manipulation Language (数据操作语言),用来对数据库中的数据记录进行增删改操作。

DML - 添加数据:

  1. 给制定字段添加数据:
    INSERT INTO 表名 (字段名 1,字段名 2,…) VALUES (值 1,值 2,…);
  2. 给全部字段添加数据:
    INSERT INTO 表名 VALUES (值 1,值 2,…);
  3. 批量添加数据:
    INSERT INTO 表名(字段名 1,字段名 2,…) VALUES (值 1,值 2,…),(值 1,值 2,…);
    INSERT INTO 表名(值 1,值 2,…),(值 1,值 2,…),(值 1,值 2,…);
  4. DML - 修改数据:
    UPDATE 表名 SET 字段名1 = 值1字段名2 = 值2 ,…【WHERE 条件】;
  5. DML - 删除数据:
    DELETE FROM 表名【WHERE 条件】

# DQL - 介绍

DQL 英文全称是 Data Query Language (数据查询语言),数据查询语言,用于查询数据库中表的记录。查询关键字:SELECT
DQL - 基本查询:

  1. 查询多个字段:
    SELECT 字段,字段 2,字段 3 … FROM 表名;
    SELECT * FROM 表名;
  2. 设置别名:
    SELECT 字段 1【 AS 别名】,字段 2【 AS 别名】 … FROM 表名;
  3. 去除重复记录:
    SELECT DISTINCT 字段列表 FROM 表名;
  4. DQL - 条件查询
    • 语法:
      SELECT 字段列表 FROM 表名 WHERE 条件列表;
    • 条件:
      比较运算符:
比较运算符 功能
> 大于
>= 大于等于
= 等于
<>!= 不等于
BETWEEN…AND 在某个范围之内(含最小、最大值)
IN(…) 在 IN 之后的列表中的值,多选一
LIKE 占位符 模糊匹配(… 匹配单个字符,% 匹配热议字符)
IS NULL 是 NULL

逻辑运算符:

逻辑运算符 功能
AND&& 并且(多个条件同时成立)
OR|| 或者(多个条件任意一个成立)
NOT 或! 非,不是
  1. DQL- 聚合函数
  • 介绍:将一列数据作为一个整体,进行纵向计算。
  • 常见聚合函数:
函数 功能
COUNT 统计数量
MAX 最大值
MIN 最下值
AVG 平均值
SUM 求和
  • 语法:
    SELECT 聚合函数(字段列表) FROM 表名;
  1. DQL - 分组查询
  • 语法
    SELECT 字段列表 FROM 表名【WHERE 条件】 GROUP BY 分组字段名【HAVING 分组后过滤条件】;
  • wherehaving 区别:
    • 执行时机不同: where 是分组之前进行过滤,不满足 where 条件,不参与分组;而 having 是分组之后对结果进行过滤;
    • 判断条件不同: where 不能对聚类函数进行判断,而 having 可以。
      【注意】
      执行顺序:where > 聚合函数 > having
      分组之后,查询的字段一般为聚合函数和分组字段,那其他字段无任何意义
  1. DQL - 排序查询
  • 语法
    • SELECT 字段列表 FROM 表名 ORDER BY 字段 1 排序方式 1,字段 2 排序方式 2;
  • 排序方式
    • ASC (ascend):升序(默认)
    • DESC (descend):降序

【注意】 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。

  1. DQL - 分页查询
    • LIMIT 控制查询的起始位置和条目数:
    • OFFSET 指定起始索引, LIMIT 指定查询条目数:
      SELECT 字段列表 FROM 表名 LIMIT 查询条目数 OFFSET 起始索引;

【注意】

  • 起始索引从 0 开始,起始索引 = (查询页数 - 1)* 每页显示记录数
  • 分页查询是数据库的方言,不同的数据库有不同的实现, MYSQL 中是 LIMIT
  • 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10
  • 如果查询无结果,会返回空的结果集,不会报错。

# DCL - 介绍

DCL 英文全称 Data Control Language (数据控制语言),用来管理数据库用户、控制数据库的访问权限。

  1. DCL - 管理用户
  • 查询用户:
    USE mysql;
    SELECT * FROM user;
  • 创建用户
    CREATE USER ‘用户名’@‘主机名’ IDENTIFIED BY ‘密码’;
  • 修改用户密码
    ALTER USER ‘用户名’@‘主机名’ IDENTIFIED WITH mysql_native_password BY ‘新密码’;
  • 删除用户
    DROP USER ‘用户名’@‘主机名’;
    【注意】
  • 主机名可以使用 % 通配,示例: 'root'@'localhost' 表示只能在本地登录; 'root'@'%' 表示可以在任意主机登录
  • 这类 SQL 开发人员操作的比较少,主要是 DBA(Database Administrator 数据库管理员)使用。
  1. DCL - 权限控制
    MySQL 中定义了很多种权限,但是常用的就一下几种:
权限 说明
ALLALL 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 主表名

# 多表查询

多表关系
项目开发中,在进行数据库表格结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本分为三种: 一对多(多对一)、多对多、一对一。

  1. 一对多(多对一):
    案例:部门与员工的关系
    关系:一个部门对应多个员工,一个员工对应一个部门
    实现:在多的一方(员工表)建立外键,指向一的一方(部门表)的主键
  2. 多对多:
    案例:学生与课程的关系
    关系:一个学生可以选修对门课程,一门课程也可以供多个学生选择
    实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
  3. 一对一:
    案例:用户与用户详情的关系
    关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提高操作效率。
    实现:在任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(UNIQUE)
    多表查询概述:
    概述:指从多张表中查询数据。
    笛卡尔积:笛卡尔乘积是指在数学中,两个集合 A 集合和 B 集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)。
    多表查询分类:
  4. 连接查询:
    • 内连接:相当于查询 A、B 交集部分数据
    • 外连接:
      • 左外连接:查询左表所有数据,以及两张表交集部分数据
      • 右外连接:查询右表所有数据,以及两张表交集部分数据
    • 自连接:当前表与自身的连接查询,自连接必须使用表别名
  5. 子查询:
    • 连接查询 - 内连接(查询两表交集的部分)
  6. 内连接查询语法: (A inner join B:AB两表值都存在)
    • 隐式内连接:
      • SELECT 字段列表 FROM 表 1,表 2 WHERE 条件…;
    • 显示内连接:
      • SELECT 字段列表 FROM 表 1【INNER】JOIN 表 2 ON 连接条件…;
  7. 连接查询 - 外连接: (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 表 1 LEFT【OUTER】JOIN 表 2 ON 条件…;
    • 右外连接:
      • SELECT 字段列表 FROM 表 1 RIGHT【OUTER】JOIN 表 2 ON 条件…;
  1. 连接查询 - 自连接:
  • 自连接查询语法:
    • SELECT 字段列表 FROM 表 A 别名 A JOIN 表 A 别名 B ON 条件…;
  • 自连接查询,可以是内连接查询,也可以是外连接查询。
  1. 联合查询 - 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 语句中的 WHERESELECTFROMHAVING 子句中。
子查询语句分类:

  • 单行子查询:子查询结果为单行单列,操作符有: =<><<=>>=
  • 多行子查询:子查询结果为多行单列或多行多列,操作符有: INANYALL