MySQL 学习记录 1

原文:https://blog.iyatt.com/?p=12631

1 前言

去年年初报考 3 月的计算机二级(C 语言)【https://blog.iyatt.com/?p=9266 】考过了,这次打算报考 3 月的计算机三级(数据库)。数据库这一块,很久之前用过 SQLite,基本没怎么深入学习。准备现学 MySQL,主要是面向应用目的,顺带后续结合开发。三级考试似乎是用微软的 SQL Server,这个问题不大,很多东西都是相通的,MySQL 熟练使用,其它估计也不是问题。

2 环境

  • MySQL 社区版 8.0.35
  • IDEA 2023:之前学 Kotlin 和 Android 开发的时候安装的,里面也有内置 DataGrip,用来图形化操作数据库很方便,也支持 SQL 语句提示,作为辅助工具。(https://blog.iyatt.com/?p=12618)

注:

  • 数据库中的关键字用大写或者小写都行,但是一般应该是用大写比较规范,读代码的时候一眼明了。至于自己命名部分的,像数据库名、表名等等,在 Windows 下大小写等同,Linux 下默认是会区分大小写的。MySQL 实际应用中应该还是在 Linux 服务器上为主,开始学习的时候还是规范大小写比较好,形成习惯。
  • SQL 语句结束使用分号。
  • 下面示例用法中使用中括号的语句代表可选。

3 数据类型

3.1 字符串类型

\begin{array}{|l|l|}
\hline
类型 & 描述 \\
\hline
CHAR & 纯文本字符串,字符串长度是固定的。当实际字段内容小于定义的长度时,MySQL 会用空白空白符好补足。 \\
\hline
VARCHAR & 纯文本字符串,字符串长度是可变的。\\
\hline
BINARY & 二进制字符串,字符串长度是固定的。 \\
\hline
VARBINARY & 二进制字符串,字符串长度是可变的。\\
\hline
TINYTEXT & 二进制字符串,最大为 255 个字节。\\
\hline
TEXT & 二进制字符串,最大为 65K。\\
\hline
MEDIUMTEXT & 二进制字符串,最大为 16M。 \\
\hline
LONGTEXT & 二进制字符串,最大为 4G。\\
\hline
ENUM & 枚举;每个列值可以分配一个 ENUM 成员。 \\
\hline
SET & 集合;每个列值可以分配零个或多个 SET 成员。 \\
\hline
\end{array}

3.2 数字类型

\begin{array}{|l|l|}
\hline
类型 & 描述 \\
\hline
TINYINT & 一个非常小的整数,最大为 1 个字节。\\
\hline
SMALLINT & 一个小整数,最大为 2 个字节。\\
\hline
MEDIUMINT & 一个中等大小的整数,最大为 3 个字节。\\
\hline
INT & 标准整数,最大为 4 个字节。\\
\hline
BIGINT & 一个大整数,最大为 8 个字节。\\
\hline
DECIMAL & 一个定点数。\\
\hline
FLOAT & 单精度浮点数,最大为 4 个字节。\\
\hline
DOUBLE & 双精度浮点数,最大为 8 个字节。\\
\hline
BIT & 按位存储。\\
\hline
\end{array}

3.3 布尔类型

MySQL 没有内置的布尔类型,但是有 BOOLEAN 和 BOOL 关键字,内部当做 TINYINT 类型处理,TRUE 对应 1,FALSE 对应 0。

3.4 日期和时间类型

\begin{array}{|l|l|}
\hline
类型 & 描述 \\
\hline
DATE & CCYY-MM-DD 格式的日期值 \\
\hline
TIME & hh:mm:ss 格式的时间值 \\
\hline
DATETIME & CCYY-MM-DD hh:mm:ss 格式的日期和时间值 \\
\hline
TIMESTAMP & CCYY-MM-DD hh:mm:ss 格式的时间戳值 \\
\hline
YEAR & CCYY 或 YY 格式的年份值 \\
\hline
\end{array}

3.5 二进制类型

\begin{array}{|l|l|}
\hline
类型 & 描述 \\
\hline
TINYBLOB & 最大为 255 个字节。\\
\hline
BLOB & 最大为 65K。\\
\hline
MEDIUMBLOB & 最大为 16M。\\
\hline
LONGBLOB & 最大为 4G。\\
\hline
\end{array}

3.6 空间数据类型

\begin{array}{|l|l|}
\hline
类型 & 描述 \\
\hline
GEOMETRY & 任何类型的空间值 \\
\hline
POINT & 使用横坐标和纵坐标表示的一个点 \\
\hline
LINESTRING & 一条曲线(一个或多个 POINT 值) \\
\hline
POLYGON & 一个多边形 \\
\hline
GEOMETRYCOLLECTION & GEOMETRY 值的集合 \\
\hline
MULTILINESTRING & LINESTRING 值的集合 \\
\hline
MULTIPOINT & POINT 值的集合 \\
\hline
MULTIPOLYGON & POLYGON 值的集合 \\
\hline
\end{array}

3.7 JSON 类型

MySQL 从 5.7.8 开始支持 JSON 数据类型。

4 符号

4.1 比较运算符

\begin{array}{|l|l|}
\hline
符号 & 描述 \\
\hline
\gt & 大于 \\
\hline
\gt= & 大于等于 \\
\hline
\lt & 小于 \\
\hline
\lt= & 小于等于 \\
\hline
= & 等于 \\
\hline
\lt\gt 或 != & 不等于 \\
\hline
BETWEEN ... AND ... & 在某个范围之内(含最小和最大值) \\
\hline
IN\ (...) & 在列表中的值(多选一)\\
\hline
LIKE\ 占位符 & 模糊匹配(\_匹配单个字符,\% 匹配任意多个字符)\\
\hline
IS NULL & 为空 \\
\hline
\end{array}

4.2 逻辑运算符

\begin{array}{|l|l|}
\hline
符号 & 描述 \\
\hline
AND 或 \&\& & 和,多个条件同时成立 \\
\hline
OR 或 || & 或,任意一个条件成立 \\
\hline
NOT 或 | & 否 \\
\hline
\end{array}

5 DDL

Data Definition Language,数据定义语言

5.1 数据库操作

查询所有数据库

SHOW DATABASES;

file

创建数据库

CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则]

file

使用数据库

USE 数据库名

file

查询当前使用的数据库

SELECT DATABASE();

file

5.2 表操作

表操作前要先通过 USE 指定使用的数据库

创建表

CREATE TABLE 表名 (
字段1 字段1的类型 [COMMENT 字段1的注释],
字段2 字段2的类型 [COMMENT 字段2的注释],
字段3 字段3的类型 [COMMENT 字段3的注释],
......
);

file

查看当前数据库中的所有表

SHOW TABLES;

file

查看表结构

DESC 表名

file

查看创建表的语句

SHOW CREATE TABLE 表名

file

表添加字段

ALTER TABLE 表名 ADD 字段 类型 [COMMENT 注释] [约束]

file

表修改字段类型

ALTER TABLE 表名 MODIFY 字段 新类型 [COMMENT 注释] [约束]

file

表修改字段名和字段类型

ALTER TABLE 表名 CHANGE 旧字段 新字段 新类型 [COMMENT 注释] [约束

file

表删除字段

ALTER TABLE DROP 表名

file

修改表名

ALTER TABLE 表名 RENAME TO 新表名

file
file

删除表

DROP TABLE [IF EXISTS] 表名

file

删除表中的所有数据但是保留结构

TRUNCATE TABLE 表名

6 DML

Data Manipulation Language,数据操作语言

给指定字段添加数据

INSERT INTO 表名 (字段1, 字段2,...) VALUES (值1, 值2,...)

file

给全部字段添加数据

INSERT INTO 表名 VALUES (值1, 值2, ...);

file

file

修改数据

UPDATE 表名 SET 字段1=值1, 字段2=值2,... [WHERE 条件];

file
file

删除数据

DELETE FROM 表名 [WHERE 条件];

file
file

7 DQL

Data Query Language,数据查询语言

7.1 基本查询

# 查询指定字段
SELECT 字段1, 字段2, ... FROM 表名;# 查询所有字段
SELECT * FROM 表名;

file

条件查询

SELECT 字段列表 FROM 表名 WHERE 条件

file

7.2 聚合函数

常用聚合函数

\begin{array}{|l|l|}
\hline
函数 & 描述 \\
\hline
COUNT & 统计数量 \\
\hline
MAX & 最大值 \\
\hline
MIN & 最小值 \\
\hline
AVG & 平均值 \\
\hline
SUM & 求和 \\
\hline
\end{array}

使用

SELECT 聚合函数(字段列表) FROM 表名

file

7.3 分组查询

SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段 [HAVING 分组后的过滤条件]

file

统计男女数量
file

统计男女各自的平均年龄
file

首先用 WHERE 筛选出年龄大于 20 的,再根据城市分组,然后 HAVING 从分组中找 COUNT 计数大于 1 的,最后 SELECT 显示出对应的 city 和数量。
file
file

7.4 排序查询

SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式, 字段2 排序方式, ...

ASC 升序,默认;
DESC 降序。

根据年龄排序(升序)
file

按年龄降序排序,年龄相同时会采用第二个字段身高排序(不指定默认升序)
file

7.5 分页查询

SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;

起始索引从 0 开始,和大多数编程语言里的数组索引一样。
下面示例是查询从索引 3 开始(第 4 个)的 3 个数据
file

8 DCL

Data Control Language,数据控制语言

8.1 用户管理

查询用户

USE mysql;
SELECT * FROM user;

file

创建用户

CREATE USER "用户名"@"主机名" IDENTIFIED BY "密码";

其中 localhost 指本地主机,如果要任意主机都可访问,可以使用 %

file

file

修改用户密码

ALTER USER "用户名"@"主机名" IDENTIFIED WITH mysql_native_password BY "新密码";

file

删除用户

DROP USER "用户名"@"主机名";

file

8.2 权限控制

常用权限

\begin{array}{|l|l|}
\hline
权限 & 描述 \\
\hline
ALL/ALL\ PRIVILEGES & 所有权限 \\
\hline
SELECT & 查询数据 \\
\hline
INSERT & 插入数据 \\
\hline
UPDATE & 修改数据 \\
\hline
DELETE & 删除数据 \\
\hline
ALTER & 修改表 \\
\hline
DROP & 删除数据库/表/试图 \\
\hline
CREATE & 创建数据库/表 \\
\hline
\end{array}

查询权限

SHOW GRANTS FOR "用户名"@"主机名";

file

授予权限

GRANT 权限列表 ON 数据库名.表名 TO "用户名"@"主机名";

撤销权限

REVOKE 权限列表 ON 数据库名.表名 FROM "用户名"@"主机名";

9 常用内置函数

9.1 字符串函数

\begin{array}{|l|l|}
\hline
函数 & 描述 \\
\hline
CONCAT(S1, S2,...,Sn) & 字符串拼接 \\
\hline
LOWER(S) & 将字符串转为小写 \\
\hline
UPPER(S) & 将字符串转为大写 \\
\hline
LPAD(S, n, pad) & 字符串左侧填充,用 pad 填充 S 的左侧,使总长度达到 n \\
\hline
RPAD(S, n, pad) & 字符串又填充,用 pad 填充 S 的右侧,使总长度达到 n \\
\hline
TRIM(S) & 去掉字符串头尾的空格 \\
\hline
SUBSTRING(S, start, len) & 返回字符串 S 从 start 开始的 len 个长度的字符串 \\
\hline
\end{array}

file
file
file
file
file
file
file

9.2 数值函数

\begin{array}{|l|l|}
\hline
函数 & 描述 \\
\hline
CEIL(x) & 向上取整 \\
\hline
FLOOR(x) & 向下取整 \\
\hline
MOD(x, y) & 计算 x / y 的模 \\
\hline
RAND() & 生成 0-1 之间的随机数 \\
\hline
ROUND(x, y) & 求 x 的四舍五入值,保留 y 位小数 \\
\hline
\end{array}

file
file
file
file
file

9.3 日期函数

\begin{array}{|l|l|}
\hline
CURDATA() & 返回当前日期 \\
\hline
CURTIME() & 返回当前时间 \\
\hline
NOW() & 返回当前日期和时间 \\
\hline
YEAR(date) & 获取 date 的年份 \\
\hline
MONTH(date) & 获取 date 的月份 \\
\hline
DAY(date) & 获取 date 的日期 \\
\hline
DATE\_ADD(date, INTERVAL expr type) & 返回 date 加上时间间隔 expr 后的时间值 \\
\hline
DATEDIFF(date1, date2) & 返回 date1 和 date2 之间的天数差值 \\
\hline
\end{array}

file
file
file
file
file
file
file

不得不感慨从小学开始读书至今已经过去 5974 天了
file

9.4 流程函数

\begin{array}{|l|l|}
\hline
日期 & 函数 \\
\hline
IF(value, t, f) & 如果 value 为 TRUE,则返回 t,否为返回 f \\
\hline
IFNULL(value1, value2) & 如果 value1 不为空则返回 value1,否则返回 value2 \\
\hline
CASE\ WHEN\ [val1]\ THEN\ [res1]\ ...\ ELSE\ [default]\ END & 如果 val1 为 TRUE,返回res1,...,否则返回 default 默认值 \\
\hline
CASE\ expr\ WHEN\ [val1]\ THEN\ [res1]\ ...\ ELSE\ [default]\ END & 如果 expr 等于val1,返回 res1,...,否则返回default默认值 \\
\hline
\end{array}

file

file

file

file

file

10 约束

常用约束

\begin{array}{|l|l|l|}
\hline
约束 & 描述 & 关键字 \\
\hline
非空约束 & 限制字段数据不能为 NULL & NOT NULL \\
\hline
唯一约束 & 字段的所有数据都是唯一的,不能重复 & UNIQUE \\
\hline
主键约束 & 主键是一行数据的唯一标识,要求非空且唯一 & PRIMARY\ KEY \\
\hline
默认约束 & 未指定字段的值采用默认值 & DEFAULT \\
\hline
检查约束(8.0.16 以后)& 保证字段值满足某条件 & CHECK \\
\hline
外键约束 & 让两张表的数据建立连接,保证数据的一致性和完整性 & FOREIGN\ KEY \\
\hline
\end{array}

10.1 一般约束示例

创建一个满足下面结构要求的表

  • id:唯一标识,字段类型 INT,约束条件:主键且自动增长
  • name:姓名,字段类型 VARCHAR(10),约束条件:不为空且唯一
  • age:年龄,字段类型 TINYINT,约束条件:不小于 0 且不超过 200
  • status:身体健康状态,字段类型 CHAR(1),约束条件:不指定默认为 1
  • gender:性别,字段类型 CHAR(1),约束条件:值为男或女

创建表

CREATE TABLE new_user (id INT PRIMARY KEY AUTO_INCREMENT COMMENT "唯一标识",name VARCHAR(10) NOT NULL UNIQUE COMMENT "姓名",age TINYINT CHECK ( age >=0 && age <= 200 ),status CHAR(1) DEFAULT "1" COMMENT "健康状态",gender CHAR(1) CHECK ( gender = "男" || gender = "女" ) COMMENT "性别"
) COMMENT "用户表";

插入数据验证:
ID 可以不用填写,提交自动从 1 开始生成
当 name 重复时,提交报错
file
当年龄超出约束范围,提交报错
file
status 不填写,提交默认为 1
当性别填写非男非女时,提交报错
file

10.2 外键约束示例

10.2.1 创建表时添加外键

CREATE TABLE 表名 (字段名 类型,...[CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名)
);

这里先创建一个父表

CREATE TABLE classes (id TINYINT COMMENT "班级标识" PRIMARY KEY , # 主键约束name CHAR(2) COMMENT "班名"
) COMMENT "班级表";

父表插入内容

INSERT INTO classes VALUES(1, "1班"),(2, "2班"),(3, "3班");

file

创建一个关联到父表的子表

CREATE TABLE students (name VARCHAR(10) COMMENT "姓名",age TINYINT COMMENT "年龄",class_id TINYINT COMMENT "班级标识",CONSTRAINT fk_students_classes_id FOREIGN Key (class_id) REFERENCES classes(id)
) COMMENT "学生表";

子表插入数据

INSERT INTO students VALUES("小强", 19, 1),("小红", 20, 2),("小张", 20, 3),("小军", 18, 2);

file

如果尝试删除父表中的行数据就会提示不能操作
file

10.2.2 现有表添加外键

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);

假如是已经创建了一张表

CREATE TABLE stu (name VARCHAR(10) COMMENT "名字",class_id TINYINT COMMENT "班级标识"
) COMMENT "学生表";

子表插入数据

INSERT INTO stu VALUES("小明", 1),("小红", 2),("小强", 3);

file

后期添加外键约束

ALTER TABLE stu ADD CONSTRAINT fk_stu_class_id FOREIGN KEY (class_id) REFERENCES classes(id);

file

10.2.3 删除外键

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

file

外键名称可以通过查看表的创建语句看到

SHOW CREATE TABLE 表名

file

file

10.2.4 外键约束行为

\begin{array}{|l|l|}
\hline
行为 & 描述 \\
\hline
NO ACTION & 父表中删除或更新记录时,首先检查该记录是否有对应外键,有则不允许删除或更新 \\
\hline
RESTRICT & 作用同上,只是 RESTRICT 是在操作发生前就起作用,而 NO ACTION 是在删除或更新操作触发时才起作用,可以看做延迟检查。默认行为。 \\
\hline
CASCADE & 父表中删除或更新记录时,首先检查记录是否有对应外键,如果有,则也删除或更新外键在子表中的记录 \\
\hline
SET NULL & 父表中删除记录时,首先检查记录是否有对应外键,有则设置子表中该外键为 NULL(需要改外键允许取 NULL) \\
\hline
\end{array}

指定外键约束行为

```mysql
CREATE TABLE 表名 (字段名 类型,...[CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名) ON UPDATE 更新时行为 ON DELETE 删除时行为;
);

```mysql
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名(主表字段名) ON UPDATE 更新时行为 ON DELETE 删除时行为;

注:如果已有外键约束,要修改行为,需要先删除原有的外键约束,然后重新建立外键时指定行为。

示例:
创建一个父表

CREATE TABLE classes (id TINYINT COMMENT "班级标识" PRIMARY KEY , # 主键约束name CHAR(2) COMMENT "班名"
) COMMENT "班级表";

父表插入内容

INSERT INTO classes VALUES(1, "1班"),(2, "2班"),(3, "3班");

创建一个子表,外键约束行为都是 CASCADE

CREATE TABLE students (name VARCHAR(10) COMMENT "姓名",age TINYINT COMMENT "年龄",class_id TINYINT COMMENT "班级标识",CONSTRAINT fk_students_classes_id FOREIGN Key (class_id) REFERENCES classes(id) ON UPDATE CASCADE ON DELETE CASCADE
) COMMENT "学生表";

子表插入数据

INSERT INTO students VALUES("小强", 19, 1),("小红", 20, 2),("小张", 20, 3),("小军", 18, 2);

修改父表
file
子表同步更新了 id
file

删除父表数据
file
子表同步删除了
file

如果设置的外键行为是 SET NULL,则修改父表或删除子表的某行元素后,子表中对应的外键会改为 NULL。
file

11 多表查询

11.1 关系

11.1.1 一对一

比如学生可以有学生信息,也有社会信息,分别建立一张表,可以通过身份证号建立外键关联起来
创建一张学生信息表

CREATE TABLE student (id CHAR(1) COMMENT "身份证号",name VARCHAR(10) COMMENT "姓名",name_of_school VARCHAR(36) COMMENT "学校名"
) COMMENT "学生信息";

插入数据

INSERT INTO student VALUES("1", "小强", "A school"),("2", "小红", "B school"),("3", "小张", "C school");

file

创建一张社会信息表

CREATE TABLE person (id CHAR(1) COMMENT "身份证号" PRIMARY KEY,name VARCHAR(10) COMMENT "姓名",age TINYINT COMMENT "年龄",address VARCHAR(128) COMMENT "地址"
) COMMENT "社会信息";

插入数据

INSERT INTO person VALUES("1", "小强", 20, "AAA"),("2", "小红", 19, "BBB"),("3", "小张", 20, "CCC");

file

建立外键

ALTER TABLE studentADD CONSTRAINT fk_student_person_idFOREIGN KEY (id)REFERENCES person (id);

查询
file

11.1.2 一对多

一个学生只属于一个班,一个班里有多个学生。
创建一个学生表

CREATE TABLE student_class (name CHAR(2) COMMENT "名字",class_id CHAR(1) COMMENT "所属班级代号"
) COMMENT "学生-班级表";

插入数据

INSERT INTO student_class VALUES ("小强", "1"),("小张", "2"),("小红", "3"),("小刚", NULL);

file
创建班级表

CREATE TABLE classes (id CHAR(1) COMMENT "班级代号" PRIMARY KEY,name CHAR(3) COMMENT "班级名称"
) COMMENT "班级表";

插入数据

INSERT INTO classes VALUES ("1", "火箭班"),("2", "实验班"),("3", "平行班");

file

建立外键

ALTER TABLE student_classADD CONSTRAINT fk_student_class_idFOREIGN KEY (class_id)REFERENCES classes (id);

11.1.3 多对多

一个学生可以上多门课,每门课可以有多个学生上,这就是一种多对多的关系。
首先创建一个学生表

CREATE TABLE stu (id CHAR(1) COMMENT "学号" PRIMARY KEY,name CHAR(2) COMMENT "姓名"
) COMMENT "学生表";

插入数据

INSERT INTO stu VALUES ("1", "小强"),("2", "小张"),("3", "小红");

file
再创建一个课程表

CREATE TABLE course (id CHAR(1) COMMENT "课程代号" PRIMARY KEY ,name CHAR(2) COMMENT "课程名称"
) COMMENT "课程表";

插入数据

INSERT INTO course VALUES("1", "高数"),("2", "大物"),("3", "英语");

file
再创建一张表,建立外链关联两张表

CREATE TABLE stu_course (stu_id CHAR(1) COMMENT "学号",course_id CHAR(1) COMMENT "课程代号",CONSTRAINT fk_stu_course_stu_id FOREIGN KEY (stu_id) REFERENCES stu(id),CONSTRAINT fk_stu_course_course_id FOREIGN KEY (course_id) REFERENCES course(id)
) COMMENT "学生课表";

插入数据

INSERT INTO stu_course VALUES("1", "2"),("2", "1"),("2", "3"),("3", "1"),("3", "2"),("3", "3");

file

11.2 内连接

内连接主要是查询两张表的交集部分,示例使用上面一对多创建的表。

隐式内连接

SELECT 字段列表 FROM 表1, 表2 WHERE 条件

file

显式内连接

SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件;

file

11.3 外连接

查询其中一张表及两张表交集的部分
左外连接(查询表1及表1和表2的交集部分),右外连接,把 LEFT 改成 RIGHT 就行,也可以把表1和表2对换,一样的效果

SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;

还是使用前面一对多创建的表演示
file
file

11.4 自连接

可以是内连接也可以是外连接

SELECT 字段列表 FROM 表A 别名1 JOIN 表A 别名2 ON 条件;

这里创建一张表用于演示

CREATE TABLE emp (id TINYINT COMMENT "工号",name VARCHAR(10) COMMENT "姓名",mid TINYINT COMMENT "领导的工号"
) COMMENT "职工表";

插入数据

INSERT INTO emp VALUES(1, "AAA", NULL),(2, "BBB", 1),(3, "CCC", 1),(4, "DDD", 2),(5, "EEE", 2),(6, "FFF", 3);

file

内连接
file

file

外连接
file

左外连接查询结果中,左边罗列出所有职工,右边是对应职工的领导,没有领导的就显示 NULL
右外连接查询结果中,右边是罗列出所有职工,左边给出对应的下属,没有下属就显示 NULL

11.5 联合查询

UNION [ALL]

这里随便创建了两张表用于演示查询,使用 UNINO ALL 会直接把两张表的结果拼起来

SELECT * FROM test1
UNION ALL
SELECT * FROM test2;

file

如果去掉 ALL,只使用 UNINO,则呈现的结果是去除重复的
file

11.6 子查询/嵌套查询

11.6.1 标量子查询

用查询到的一个结果作为条件进一步查询

这里使用前面创建的两张表演示
file

首先在班级表里查询火箭班的 ID,然后再到学生表中查询具有这个 ID 的学生信息

SELECT * FROM student_classWHERE class_id = (SELECT id FROM classes WHERE name = "火箭班");

file

11.6.2 列子查询

常用的操作符

\begin{array}{l l}
操作符 & 描述 \\
\hline
IN & 在指定的集合范围内 \\
NOT IN & 不在指定的集合范围内 \\
ANY & 子查询返回列表中,有任意一个满足即可 \\
SOME & 与 ANY 等同,使用 SOME 的地方都可以使用 ANY \\
ALL & 子查询返回列表的所有值都必须满足
\end{array}

前面是先查询出一个结果,再用这个结果作为条件查询。列子查询则是查询出符合某条件的一列结果,将这一列结果作为条件进行查询。
有下面两张表:
file
file

查询班级平均成绩大于 80 的班级中的学生信息

SELECT * FROM student WHERE class_id in (SELECT class_idFROM classWHERE average_grades > 80);

file

11.6.3 行子查询

列子查询是同时筛选一列的多行,行子查询就是筛选一行的多列(多表头)
在上面表上加上个人学生成绩
file
现在要找出在火箭班中成绩与班级平均成绩相同的

SELECT * FROM student WHERE (grades, class_id) = (SELECT average_grades, class_id FROM class WHERE name = '火箭班');

file

11.6.4 表子查询

筛选多行多列
将学生表中年龄大于 16 的数据筛选出来,将这些数据和班级表结合起来外连接查询

SELECT s.name, c.name FROM (SELECT * FROM student WHERE age > 16) s LEFT JOIN class c on s.class_id = c.class_id;

file

12 事务

MySQL 中默认每次执行修改数据指令后会立即提交(默认自动事务),但是这种情景中(A向B转账,首先查询A的余额,余额足够,从A的余额扣除,再给B增加余额),可能就会出现问题(如果在A扣除余额后和在B增加余额之间的操作中出现异常导致终止),这种情形下A的余额扣了,但是B的余额没有增加。
MySQL 中的(手动)事务则可以应对这个情况,可以将整个流程操作作为一个事务(查询A余额,扣除A余额,增加B余额),中间的操作不会最终修改原始数据,只是暂存,操作成功最后提交修改就行,操作失败放弃暂存的操作,原始数据不修改(回滚)。

创建用于测试的表

CREATE TABLE account(name varchar(2),balance int
);INSERT into account VALUES('小明', 2000),('小红', 2000);

恢复数据

UPDATE account set balance = 2000 WHERE name = '小明' or name = '小红';

查看事务提交方式
0 为手动,1 为自动

SELECT @@autocommit;

file

改为手动就把这个变量值设置为 0

SET @@autocommit = 0;

提交事务
在手动事务状态(或显式启用事务)下,执行了修改操作不会直接修改,在执行完每个指令或者一系列指定后手动执行这个指令才会提交生效

COMMIT;

回滚事务

ROLLBACK;

显式启用事务

start transaction;

转账模拟实现

# 查询余额
SELECT * FROM account;# 小明余额 -1000
UPDATE account SET balance = balance - 1000 WHERE name = '小明';# 小红余额 +1000
UPDATE account SET balance = balance + 1000 WHERE name = '小红';# 查询余额
SELECT * FROM account;

模拟异常
我在小明扣除转出金额核小红增加金额中间添加了一个错误的语句
file

这样就出现了小明余额扣除,但是小红余额没有增加的情况
file


可以显式启用事务,在操作时遇到异常就执行回滚,则会恢复原数据并结束当前事务。

事务这个设计有点像 Git,添加删除修改等操作后只是添加到暂存区,最终操作完使用 commit 才提交。只是 MySQL 默认状态每执行一次操作就会自动提交一次,设置显式事务后,则不会自动提交,中间可以回滚放弃修改。

12.1 特性(ACID)

  • 原子性(Atomicity)

事务是最小的操作单元,一个事务可以是一个操作或者多个操作的集合(但不可分割),其中任一组员执行失败就是整个事务的失败,而全部执行成功,事务才执行成功。

  • 一致性(Consistency)

一致性可以体现在上面的转账案例中,小明转出了钱,余额减少了,转给小红了,小红余额对应增加了,不会出现小明余额减少了,但小红余额没有增加的情况。

  • 隔离性(Isolation)

多个事务并发执行时互不影响,各自独立执行。

  • 持久性(Durability)

事务被提交(或回滚)对数据的修改就是永久的,写入了硬盘中的数据库文件里了。

12.2 并发事务存在的问题

  • 脏读
    一个事务读到另外一个事务还没有提交的数据

  • 不可重复读
    一个事务先后读取同一条记录,但两次读取的数据不同。一个事务有两个读取操作,第一次读取后,在第二次读取前,另外一个事务对数据进行了修改,第二次读取时数据就和第一次不一样了。

  • 幻读
    一个事务在读取数据时,没有对应的数据,尝试插入数据的时候发现已经存在了。一个事务在读取操作的时候发现数据不存在,然后准备插入数据,在插入之前另外一个事务先执行了插入,等到原事务打算插入的时候又发现已经存在。

12.3 事务隔离级别

\begin{array}{l}
隔离级别 & 脏读 & 不可重复读 & 幻读 \\
READ\ UNCOMMITTED & &#10003 & &#10003 & &#10003 \\
READ\ COMMITTED & &#10006 & &#10003 & &#10003 \\
REPEATABLE\ READ(默认) & &#10006 & &#10006 & &#10003 \\
SERIALIZABLE & &#10006 & &#10006 & &#10006
\end{array}

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

设置事务隔离级别

SET 作用范围 TRANSACTION ISOLATION LEVEL 隔离级别;

作用范围可以写 SESSION(只在当前客户端生效)和 GLOBAL(全局)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/261194.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes(K8s)的基础概念

K8s的概念 K8S 的全称为 Kubernetes (K12345678S) &#xff08;简化全称&#xff09; Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于 管理容器化工作负载和服务&#xff0c;有助于声明式配置和自动化。它拥有庞大且快速发展的生态系统。Kubernetes 服务、支持和…

SQL防止注入工具类,可能用于SQL注入的字符有哪些

SQL注入是一种攻击技术&#xff0c;攻击者试图通过在输入中注入恶意的SQL代码来干扰应用程序的数据库查询。为了防止SQL注入&#xff0c;你需要了解可能用于注入的一些常见字符和技术。以下是一些常见的SQL注入字符和技术&#xff1a; 单引号 ​&#xff1a; 攻击者可能会尝试…

【前端工程化面试题】webpack proxy的工作原理,为什么能解决跨域问题

在 webpack 的配置文件 webpack.config.js 中有一个配置项 devServer 里面有一个属性是 proxy&#xff0c;这里面可以配置代理服务器&#xff0c;解决跨域问题&#xff0c;请参考官网。 一般来说 webpack 的代理就是说的开发服务器 webpack-dev-server。 其实不光是 webpack 其…

线阵相机之帧超时

1 帧超时的效果 在帧超时时间内相机若未采集完一张图像所需的行数&#xff0c;则相机会直接完成这张图像的采集&#xff0c;并自动将缺失行数补黑出图&#xff0c;机制有以下几种选择&#xff1a; 1. 丢弃整张补黑的图像 2. 保留补黑部分出图 3.丢弃补黑部分出图

爬虫知识--02

免费代理池搭建 # 代理有免费和收费代理 # 代理有http代理和https代理 # 匿名度&#xff1a; 高匿&#xff1a;隐藏访问者ip 透明&#xff1a;服务端能拿到访问者ip 作为后端&#xff0c;如何拿到使用代理人的ip 请求头中&#xff1a;x-forwor…

⭐北邮复试刷题106. 从中序与后序遍历序列构造二叉树__递归分治 (力扣每日一题)

106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postor…

人工智能深度学习

目录 人工智能 深度学习 机器学习 神经网络 机器学习的范围 模式识别 数据挖掘 统计学习 计算机视觉 语音识别 自然语言处理 机器学习的方法 回归算法 神经网络 SVM&#xff08;支持向量机&#xff09; 聚类算法 降维算法 推荐算法 其他 机器学习的分类 机器…

基于vue的个性化推荐餐饮系统Springboot

项目&#xff1a;基于vue的个性化推荐餐饮系统Springboot 摘要 现代信息化社会下的数据管理对活动的重要性越来越为明显&#xff0c;人们出门可以通过网络进行交流、信息咨询、查询等操作。网络化生活对人们通过网上购物也有了非常大的考验&#xff0c;通过网上进行点餐的人也…

C# Winfrom实现的肺炎全国疫情实时信息图

运行结果&#xff1a; using System; using System.Drawing; using System.Text; using NSoup; using NSoup.Nodes; using System.IO; using System.Net; using System.Text.RegularExpressions; using System.Windows.Forms;namespace Pneumonia {public partial class MainFo…

C#开发AGV地图编辑软件

C#自己开发AGV地图编辑软件&#xff1a; 1、自由添加和删除站点、停车位、小车、运行路径。 2、编辑得地图以XML文件保存。 3、导入编辑好地图的XML文件。 4、程序都是源码&#xff0c;可以直接在此基础上进行二次开发。 下载链接&#xff1a;https://download.csdn.net/d…

【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture04反向传播

lecture04反向传播 课程网址 Pytorch深度学习实践 部分课件内容&#xff1a; import torchx_data [1.0,2.0,3.0] y_data [2.0,4.0,6.0] w torch.tensor([1.0]) w.requires_grad Truedef forward(x):return x*wdef loss(x,y):y_pred forward(x)return (y_pred-y)**2…

19个Web前端交互式3D JavaScript框架和库

JavaScript &#xff08;JS&#xff09; 是一种轻量级的解释&#xff08;或即时编译&#xff09;编程语言&#xff0c;是世界上最流行的编程语言。JavaScript 是一种基于原型的多范式、单线程的动态语言&#xff0c;支持面向对象、命令式和声明式&#xff08;例如函数式编程&am…

Spring最新核心高频面试题(持续更新)

1 什么是Spring框架 Spring框架是一个开源的Java应用程序开发框架&#xff0c;它提供了很多工具和功能&#xff0c;可以帮助开发者更快地构建企业级应用程序。通过使用Spring框架&#xff0c;开发者可以更加轻松地开发Java应用程序&#xff0c;并且可以更加灵活地组织和管理应…

OpenAI全新发布文生视频模型:Sora!

OpenAI官网原文链接&#xff1a;https://openai.com/research/video-generation-models-as-world-simulators#fn-20 我们探索视频数据生成模型的大规模训练。具体来说&#xff0c;我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用对视频和…

【Vuforia+Unity】AR03-圆柱体物体识别

1.创建数据库模型 这个是让我们把生活中类似圆柱体和圆锥体的物体进行AR识别所选择的模型 Bottom Diameter:底部直径 Top Diameter:顶部直径 Side Length:圆柱侧面长度 请注意&#xff0c;您不必上传所有三个部分的图片&#xff0c;但您需要先为侧面曲面关联一个图像&#…

HarmonyOS—@Observed装饰器和@ObjectLink嵌套类对象属性变化

Observed装饰器和ObjectLink装饰器&#xff1a;嵌套类对象属性变化 概述 ObjectLink和Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步&#xff1a; 被Observed装饰的类&#xff0c;可以被观察到属性的变化&#xff1b;子组件中ObjectLink装饰器装饰的状…

动态内存管理(下)

动态内存管理&#xff08;上&#xff09;-CSDN博客&#xff08;malloc&#xff0c; realloc&#xff0c; calloc&#xff0c; free函数的用法以及注意事项等知识点&#xff09; 动态内存管理&#xff08;中&#xff09;-CSDN博客&#xff08;常见的内存出错问题) -----------…

Java 学习和实践笔记(15):面向过程和面象对象其实很简单!

学完这一节&#xff0c;才真正明白了什么叫面向对象和面向过程&#xff0c;其实很简单~ 第一个例子&#xff1a;怎样把大象装进冰箱 这个很清楚很容易地可以列出第一步。 第二个例子&#xff1a;怎样制造一台汽车 这个就很难确定哪一步做第一步。 面向过程和面向对象的区别 …

快速学习springsecurity最新版 (版本6.2)---用户认证

简介 ​ Spring Security 是 Spring 家族中的一个安全管理框架。目前比较主流的是另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富,但是shiro并不简便,这里轻量级安全框架更推荐国产安全框架satokensatoken官网 ​ 一般大型的项目都…

如何在Ubuntu部署Emlog,并将本地博客发布至公网可远程访问

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…