MySQL基础知识

MySQL 基础学习笔记

本文系统梳理MySQL基础知识点,涵盖SQL语言分类(DDL、DML、DQL、DCL、TCL)、数据类型(数值、字符串、日期时间)、表结构操作(创建、修改、删除)、数据增删改查及约束、函数、多表查询、子查询与事务控制。重点强调:使用DECIMAL存储金额、TIMESTAMP自动更新时间、UPDATE需加WHERE避免全表误改,以及事务的ACID特性与控制语句。内容全面,适合作为复习与进阶参考。


1. SQL 基础

1.1 什么是 SQL

结构化查询语言(SQL, Structured Query Language)是一种用于在关系数据库中存储和处理信息的编程语言。关系数据库以表格形式存储信息:行表示记录,列表示字段(数据属性),表与表之间通过数据值建立关系。使用 SQL 可以完成数据的存储、更新、删除、检索,以及数据库的维护与性能优化。

1.2 SQL 命令分类

分类 全称 说明 常用命令
DDL Data Definition Language 数据定义语言,用来定义数据库对象(数据库、表、字段) CREATE、DROP、ALTER、TRUNCATE
DML Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改 INSERT、DELETE、UPDATE
DQL Data Query Language 数据查询语言,用来查询数据库中表的记录 SELECT
DCL Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限 GRANT、REVOKE
TCL Transaction Control Language 事务控制语言,用来控制事务的提交与回滚 COMMIT、ROLLBACK、SAVEPOINT

记忆口诀:定(DDL)义结构、操(DML)作数据、查(DQL)询记录、控(DCL)制权限、事(TCL)务控制。


2. MySQL 数据类型

2.1 数值类型

类型 大小 有符号(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.402823466 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(标度) 的值 依赖于 M(精度) 和 D(标度) 的值 小数值(精确定点数)

要点补充:

  • 整数类型可加 UNSIGNED 修饰,表示无符号非负数。
  • FLOAT/DOUBLE 是近似值,存在精度损失;金额等要求精确的场景用 DECIMAL(M,D),M 是总位数(精度),D 是小数位数(标度)。
  • INT(11) 中的数字只影响显示宽度,不限制取值范围。

2.2 字符串类型

类型 大小 描述
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制数据
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65535 bytes 二进制形式的长文本数据
TEXT 0-65535 bytes 长文本数据
MEDIUMBLOB 0-16777215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16777215 bytes 中等长度文本数据
LONGBLOB 0-4294967295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4294967295 bytes 极大文本数据

要点补充:

  • CHAR(n) 定长:不足 n 补空格,节省计算、浪费空间;VARCHAR(n) 变长:按实际长度存储并额外记录长度,节省空间。
  • 经验法则:长度固定或很短(如性别、MD5)用 CHAR,长度可变用 VARCHAR;BLOB 存二进制(图片、文件),TEXT 存大段文本。
  • VARCHAR 的 n 按字符计,CHAR 也按字符计,实际占用字节数与字符集有关(utf8mb4 一个字符最多 4 字节)。

2.3 日期时间类型

类型 大小 范围 格式 描述
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 混合日期和时间值,时间戳

要点补充:

  • DATETIME 与 TIMESTAMP 都能存"日期+时间",区别:TIMESTAMP 范围小(存在 2038 问题)、占 4 字节、与时区相关,且列可自动维护(插入/更新时自动填充当前时间);DATETIME 与时区无关。
  • 记录"创建时间、更新时间"这类审计字段,常用 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。

3. 数据定义语言 DDL

3.1 数据库操作

操作 语法
查询所有数据库 SHOW DATABASES;
查询当前数据库 SELECT DATABASE();
创建数据库 CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则];
删除数据库 DROP DATABASE [IF EXISTS] 数据库名;
使用数据库 USE 数据库名;

3.2 表操作 ------ 查询

操作 语法
查询当前数据库所有表 SHOW TABLES;
查询表结构 DESC 表名;
查询指定表的建表语句 SHOW CREATE TABLE 表名;

3.3 表操作 ------ 创建

sql 复制代码
CREATE TABLE 表名(
    字段1 字段1类型 [COMMENT 字段1注释],
    字段2 字段2类型 [COMMENT 字段2注释],
    字段3 字段3类型 [COMMENT 字段3注释],
    ......
    字段n 字段n类型 [COMMENT 字段n注释]
)[COMMENT 表注释];

注意:[...] 为可选参数,最后一个字段后面没有逗号。

3.4 表操作 ------ 修改

操作 语法
添加字段 ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释] [约束];
修改数据类型 ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
修改字段名和字段类型 ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
删除字段 ALTER TABLE 表名 DROP 字段名;
修改表名 ALTER TABLE 表名 RENAME TO 新表名;

记忆:CHANGE 改名又改型(必须写新类型),MODIFY 只改类型不改名。

3.5 表操作 ------ 删除

操作 语法
删除表 DROP TABLE [IF EXISTS] 表名;
删除指定表,并重新创建该表(清空数据) TRUNCATE TABLE 表名;

注意:在删除表时,表中的全部数据也会被删除。


4. 数据操作语言 DML ------ 添加数据

场景 语法
给指定字段添加数据 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, ...);

注意:

  • 字符串和日期值要用单引号包裹,数值可以直接写。
  • 未指定 AUTO_INCREMENT 主键列时可省略不写,由数据库自动递增。

5. DML ------ 修改与删除数据

5.1 修改数据(UPDATE)

sql 复制代码
UPDATE 表名 SET 字段名1=值1, 字段名2=值2, ... [WHERE 条件];

示例:

sql 复制代码
UPDATE employee SET age = 30 WHERE id = 1;          -- 修改指定记录
UPDATE employee SET salary = salary * 1.1;           -- 不带 WHERE,修改全表所有记录

⚠️ 不写 WHERE 条件会更新全表数据,这是生产事故的高发点,务必养成先写 WHERE 再写 SET 的习惯。

5.2 删除数据(DELETE)

sql 复制代码
DELETE FROM 表名 [WHERE 条件];

示例:

sql 复制代码
DELETE FROM employee WHERE name = '张三';   -- 删除指定记录
DELETE FROM employee;                        -- 删除表中全部数据(表结构保留)

5.3 DELETE / TRUNCATE / DROP 对比(高频面试题)

对比项 DELETE TRUNCATE DROP
语言类别 DML DDL DDL
删除范围 可按 WHERE 删部分行 清空整表数据 整张表(结构+数据)
表结构是否保留 保留 保留 不保留
能否回滚(事务中) 可以 不可以 不可以
速度 慢(逐行删除并记录日志) 快 快
自增主键计数器 不清零 清零重新计数 随表一起删除

6. 数据查询语言 DQL(重点)

6.1 基本查询

sql 复制代码
SELECT 字段1, 字段2, ... FROM 表名;
SELECT * FROM 表名;              -- 查询所有字段
SELECT DISTINCT 字段 FROM 表名;   -- 去重:消除结果集中完全相同的行
SELECT 字段1 AS 别名, 字段2 别名 FROM 表名;   -- 列别名,AS 可省略
SELECT CONCAT(姓, 名) AS 姓名 FROM 表名;       -- 拼接列后作为一列输出

6.2 条件查询(WHERE)

sql 复制代码
SELECT 字段... FROM 表名 WHERE 条件;

比较运算符:

运算符 含义
= 等于
> / >= 大于 / 大于等于
< / <= 小于 / 小于等于
<> 或 != 不等于
BETWEEN...AND... 在某个范围内(闭区间,含两端)
IN(...) 匹配括号中任意一个值
LIKE 模糊匹配
IS NULL / IS NOT NULL 是否为空 / 不为空

逻辑运算符 :AND(并且)、OR(或者)、NOT(非)。

LIKE 通配符:

通配符 含义
% 任意多个字符,包含 0 个字符
_ 任意单个字符

示例:

sql 复制代码
SELECT * FROM employee WHERE name LIKE '张%';     -- 姓张的所有人
SELECT * FROM employee WHERE name LIKE '张_';     -- 姓张且名字为两个字
SELECT * FROM employee WHERE age IN (20, 30, 40); -- 年龄是 20/30/40
SELECT * FROM employee WHERE age BETWEEN 20 AND 30;
SELECT * FROM employee WHERE score IS NULL;       -- 注意:判空必须用 IS NULL

⚠️ NULL 的特殊性:任何值与 NULL 做比较结果都是 NULL(未知)。score = NULL 永远查不到数据,必须写 score IS NULL;!= 也查不出 NULL 行。

6.3 排序查询(ORDER BY)

sql 复制代码
SELECT 字段... FROM 表名 ORDER BY 字段1 [ASC|DESC], 字段2 [ASC|DESC];
  • ASC 升序(默认)、DESC 降序。
  • 多个排序条件:前一根列相同时,才按下一列排序。
  • 若有 WHERE,先过滤、后排序。
sql 复制代码
SELECT * FROM employee ORDER BY age ASC, salary DESC;

6.4 聚合函数

将一列数据作为一个整体,进行纵向计算。

函数 功能
COUNT(字段) 统计数量(常用 COUNT(*) 统计行数)
MAX(字段) 最大值
MIN(字段) 最小值
AVG(字段) 平均值
SUM(字段) 求和
sql 复制代码
SELECT COUNT(*) FROM employee WHERE age <= 35;
SELECT AVG(salary), MAX(salary) FROM employee;

⚠️ 聚合函数计算时忽略 NULL 值 :COUNT(score) 统计的是 score 非 NULL 的行数,与 COUNT(*) 可能不同;求平均分若想 NULL 按 0 算,需先 IFNULL(score, 0)。

6.5 分组查询(GROUP BY / HAVING)

sql 复制代码
SELECT 分组字段, 聚合函数(字段) FROM 表名 [WHERE 条件]
GROUP BY 分组字段 [HAVING 分组后条件] [ORDER BY 字段];

示例:

sql 复制代码
-- 每个部门的人数
SELECT dept, COUNT(*) FROM employee GROUP BY dept;

-- 年龄 35 岁及以下的人,根据性别分组,统计男/女年龄平均值
SELECT gender, AVG(age) FROM employee WHERE age <= 35 GROUP BY gender;

-- 查询人数大于 2 的部门
SELECT dept, COUNT(*) FROM employee GROUP BY dept HAVING COUNT(*) > 2;

WHERE 与 HAVING 的区别(必考):

对比 WHERE HAVING
执行时机 分组前过滤 分组后过滤
能否用聚合函数 不能 能

执行顺序:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。分组后能 SELECT 的只有分组字段和聚合函数,其余列的值无意义。

6.6 分页查询(LIMIT)

sql 复制代码
SELECT 字段... FROM 表名 LIMIT 起始索引, 记录条数;
  • 起始索引从 0 开始;第一页:LIMIT 0, 10,第二页:LIMIT 10, 10。
  • 公式:起始索引 = (页码 - 1) × 每页条数。
  • 只写 LIMIT 10 表示从第 0 条开始取 10 条。

7. 约束(Constraint)

约束是作用于数据表列上的规则,保证数据的完整性、正确性、有效性。

约束 关键字 作用
非空约束 NOT NULL 字段值不能为 NULL
唯一约束 UNIQUE 字段值不能重复(可为 NULL,且只允许一个 NULL)
主键约束 PRIMARY KEY 唯一 + 非空,一行数据的唯一标识,一张表只能有一个
外键约束 FOREIGN KEY 保证两张表之间数据的关联有效性
默认约束 DEFAULT 插入数据未指定该列时,自动使用默认值
自动增长 AUTO_INCREMENT 整数列自动按 1 递增,常配合主键使用

7.1 建表时定义

sql 复制代码
CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(10) NOT NULL UNIQUE,
    age INT,
    gender VARCHAR(1) DEFAULT '女',
    class_id INT,
    CONSTRAINT fk_stu_cls FOREIGN KEY (class_id) REFERENCES class(id)
);

7.2 建表后添加 / 删除

sql 复制代码
-- 添加非空 / 唯一 / 默认
ALTER TABLE student MODIFY name VARCHAR(10) NOT NULL;
ALTER TABLE student MODIFY name VARCHAR(10) UNIQUE;
ALTER TABLE student MODIFY gender VARCHAR(1) DEFAULT '男';

-- 添加 / 删除主键
ALTER TABLE student MODIFY id INT PRIMARY KEY;
ALTER TABLE student DROP PRIMARY KEY;

-- 添加 / 删除外键
ALTER TABLE student ADD CONSTRAINT fk_stu_cls FOREIGN KEY (class_id) REFERENCES class(id);
ALTER TABLE student DROP FOREIGN KEY fk_stu_cls;

7.3 外键要点

  • 语法:FOREIGN KEY (本表字段) REFERENCES 主表(主表字段)。
  • 被引用列必须是主键或唯一列;两列类型要兼容。
  • 有外键引用时,删除主表被引用的行、或修改被引用的主键值会报错;插入从表时外键值必须在主表中存在(或为 NULL)。
  • 一对一、一对多:外键放在"多"的一方;多对多:需要第三张中间表,各放一个外键。

8. 多表查询

8.1 笛卡尔积与隐式内连接

两张表无条件连接会产生笛卡尔积(行数相乘),用 WHERE 过滤掉无效结果就是隐式内连接:

sql 复制代码
-- 查询员工姓名及其部门名称
SELECT e.name, d.dept_name
FROM employee e, dept d
WHERE e.dept_id = d.id;

8.2 显式内连接(INNER JOIN)

sql 复制代码
SELECT e.name, d.dept_name
FROM employee e
INNER JOIN dept d ON e.dept_id = d.id;    -- INNER 可省略,写 JOIN 即可

内连接只返回两表能匹配上的行;无匹配员工的部门、无所属部门的员工都不会出现。

8.3 外连接(OUTER JOIN)

sql 复制代码
-- 左外连接:左表所有行都保留,右表匹配不上则为 NULL
SELECT e.name, d.dept_name
FROM employee e
LEFT JOIN dept d ON e.dept_id = d.id;

-- 右外连接:右表所有行都保留(与左外对称,实际开发中常用左外+调换表顺序代替)
SELECT e.name, d.dept_name
FROM employee e
RIGHT JOIN dept d ON e.dept_id = d.id;

典型用法:查"所有员工及其部门(包括没有部门的员工)"用左外连接;查"所有部门及其员工人数(包括没有员工的部门)"用右外连接或以 dept 为左表。

8.4 自连接

一张表和自己连接,用于表内存在层级关系的数据(如员工与领导):

sql 复制代码
-- 查询每个员工及其领导的姓名
SELECT e.name AS 员工, m.name AS 领导
FROM employee e
LEFT JOIN employee m ON e.managerid = m.id;   -- 外连接才能保留没有领导的员工

8.5 UNION 合并结果集

sql 复制代码
SELECT ... UNION SELECT ...;        -- 合并并去重
SELECT ... UNION ALL SELECT ...;    -- 合并不去重,性能更好

9. 子查询(嵌套查询)

SQL 语句中嵌套 SELECT 语句,称为子查询,外层为主查询。子查询按返回结果分为 4 类:

9.1 标量子查询(返回单个值)

sql 复制代码
-- 查询"销售部"的所有员工信息
SELECT * FROM employee
WHERE dept_id = (SELECT id FROM dept WHERE dept_name = '销售部');

可用于 WHERE、SELECT 等任何需要值的位置。

9.2 列子查询(返回一列多行)

常用 IN / ANY / ALL 配合:

sql 复制代码
-- 查询"销售部"和"市场部"的所有员工
SELECT * FROM employee
WHERE dept_id IN (SELECT id FROM dept WHERE dept_name = '销售部' OR dept_name = '市场部');

9.3 行子查询(返回一行多列)

用行构造器 (值1, 值2) 或 ROW() 与之比较:

sql 复制代码
-- 查询与"悟空"入职日期和工号都相同的员工
SELECT * FROM employee
WHERE (workno, entrydate) = (SELECT workno, entrydate FROM employee WHERE name = '悟空');

9.4 表子查询(返回多行多列)

把子查询结果当作一张临时表,与表连接或再查询:

sql 复制代码
-- 查询每个部门年龄最大的员工信息
SELECT * FROM (
    SELECT dept_id, MAX(age) AS max_age FROM employee GROUP BY dept_id
) t
JOIN employee e ON e.dept_id = t.dept_id AND e.age = t.max_age;

9.5 EXISTS 存在性子查询

sql 复制代码
-- 查询"存在员工"的部门信息
SELECT * FROM dept d
WHERE EXISTS (SELECT 1 FROM employee e WHERE e.dept_id = d.id);

子查询有结果返回 TRUE,无结果返回 FALSE,常用于替代 IN 判断关联存在性。


10. 常用函数

10.1 字符串函数

函数 用法 功能
CONCAT CONCAT(str1, str2, ...) 字符串拼接
LENGTH LENGTH(str) 获取字符串长度(按字节)
CHAR_LENGTH CHAR_LENGTH(str) 按字符计长度
UPPER / LOWER UPPER(str) 转大写 / 小写
LPAD / RPAD LPAD(str, n, pad) 左/右填充到指定长度
TRIM / LTRIM / RTRIM TRIM(str) 去除两端/左/右空格
SUBSTRING SUBSTRING(str, pos, len) 截取子串(pos 从 1 开始)
REPLACE REPLACE(str, from, to) 替换子串
INSTR INSTR(str, substr) 返回子串首次出现位置

10.2 数值函数

函数 用法 功能
ABS ABS(x) 绝对值
CEIL / FLOOR CEIL(x) 向上 / 向下取整
ROUND ROUND(x, d) 四舍五入,d 为小数位数
TRUNCATE TRUNCATE(x, d) 截断到 d 位小数(不四舍五入)
MOD MOD(x, y) 取余
RAND RAND() 返回随机浮点数 [0,1)
UUID UUID() 生成全局唯一标识串

10.3 日期函数

函数 用法 功能
NOW NOW() 返回当前日期和时间
CURDATE / CURTIME CURDATE() 当前日期 / 当前时间
YEAR / MONTH / DAY / HOUR / MINUTE / SECOND YEAR(d) 提取日期对应部分
DATE_ADD DATE_ADD(d, INTERVAL n 单位) 日期加 n 个单位
DATE_SUB DATE_SUB(d, INTERVAL n DAY) 日期减 n 个单位
DATEDIFF DATEDIFF(d1, d2) 两日期相差天数(d1 - d2)
STR_TO_DATE STR_TO_DATE(s, fmt) 字符串按格式转日期
DATE_FORMAT DATE_FORMAT(d, fmt) 日期按格式转字符串
sql 复制代码
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);              -- 7 天后
SELECT DATEDIFF('2026-10-24', '2026-01-01');        -- 相差天数
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');     -- 格式化输出

10.4 其他常用函数

函数 用法 功能
IFNULL IFNULL(x, 默认值) x 为 NULL 时返回默认值
ISNULL ISNULL(x) x 为 NULL 返回 1,否则 0
IF IF(cond, v1, v2) 条件为真返回 v1,否则 v2
CASE CASE WHEN 条件 THEN 值 ... ELSE 值 END 多分支映射
GREATEST / LEAST GREATEST(a,b,c) 返回最大 / 最小值
sql 复制代码
-- CASE 示例:按分数打等级
SELECT name, score,
       CASE WHEN score >= 90 THEN '优秀'
            WHEN score >= 60 THEN '及格'
            ELSE '不及格' END AS 等级
FROM student;

11. 数据控制语言 DCL

11.1 管理用户

sql 复制代码
-- 查询用户(用户信息存在 mysql 库的 user 表中)
USE mysql;
SELECT * FROM user;

-- 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

-- 修改密码(MySQL 5.7.6+)
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';

-- 删除用户
DROP USER '用户名'@'主机名';

主机名 表示该用户允许从哪台机器登录:localhost 只允许本机,% 允许任意主机。

11.2 权限管理

sql 复制代码
-- 查询用户权限
SHOW GRANTS FOR '用户名'@'主机名';

-- 授予权限
GRANT 权限列表 ON 数据库.表名 TO '用户名'@'主机名';
GRANT ALL ON *.* TO 'tomcat'@'%';          -- 授予所有库表的所有权限

-- 撤销权限
REVOKE 权限列表 ON 数据库.表名 FROM '用户名'@'主机名';

常见权限:ALL PRIVILEGES(所有)、SELECT、INSERT、UPDATE、DELETE、CREATE、DROP、GRANT OPTION(可转授权)。

安全实践:给业务账号只授予所需库表的最小权限,不要用 root 直连应用。


12. 事务(TCL)

12.1 概念

事务是一组要么全部成功、要么全部失败回滚的 SQL 操作集合,用于保证数据的一致性。典型场景:转账------扣款和入账必须同时成功或同时失败。

注意:只有 DML 语句(增删改) 的操作才纳入事务管理;DDL 操作会立即自动提交,无法回滚。MySQL 中 InnoDB 支持事务,MyISAM 不支持。

12.2 语法

sql 复制代码
START TRANSACTION;   -- 开启事务(或 BEGIN;)

UPDATE account SET money = money - 1000 WHERE name = 'A';
UPDATE account SET money = money + 1000 WHERE name = 'B';

COMMIT;              -- 提交事务:两条更新永久生效
-- ROLLBACK;        -- 回滚事务:撤销事务内所有未提交的修改

保存点(部分回滚):

sql 复制代码
START TRANSACTION;
INSERT INTO account VALUES (5, 'E', 100);
SAVEPOINT s1;                 -- 设置保存点
INSERT INTO account VALUES (6, 'F', 200);
ROLLBACK TO s1;               -- 只回滚到保存点,s1 之前的操作保留
COMMIT;

12.3 四大特性(ACID)

特性 说明
原子性 Atomicity 事务是不可分割的整体,要么全成功,要么全失败
一致性 Consistency 事务执行前后,数据从一个合法状态到另一个合法状态(如总额不变)
隔离性 Isolation 多个并发事务之间互不干扰
持久性 Durability 事务一旦提交,修改永久保存到数据库

12.4 并发问题与隔离级别(了解)

并发可能带来:脏读 (读到别的事务未提交的数据)、不可重复读 (两次读取同一行数据不同,因别的事务 UPDATE)、幻读(两次查询行数不同,因别的事务 INSERT)。

sql 复制代码
SELECT @@transaction_isolation;                                  -- 查看隔离级别
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL 级别;            -- 设置隔离级别
隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED ✓ ✓ ✓
READ COMMITTED(Oracle 默认) ✗ ✓ ✓
REPEATABLE READ(MySQL 默认) ✗ ✓*
SERIALIZABLE ✗ ✗(并发性能最差)

* InnoDB 通过 MVCC + 间隙锁在很大程度上避免了幻读。级别越高越安全、并发性能越差。


13. 附:SQL 语法执行顺序与学习路线

书写顺序 vs 执行顺序:

复制代码
书写:SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
执行:FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

理解执行顺序能解释很多现象:WHERE 里不能用 SELECT 定义的别名和聚合函数,HAVING 必须配合分组等。

建议后续学习路线(笔记尚未覆盖的进阶内容):

  1. 索引(INDEX)的创建与失效场景、EXPLAIN 执行计划
  2. 视图(VIEW)
  3. 存储过程、函数、触发器
  4. 锁机制与 InnoDB 存储引擎原理、MVCC
  5. SQL 优化与慢查询分析、备份恢复(mysqldump)
相关推荐
fox06334 小时前
预约类平台的责任边界建模:从一个证件办理预约平台的流程设计说起
大数据·数据库·搜索引擎·全文检索·生活
DolphinDB4 小时前
QuantLib 之外,衍生品定价还能怎么选?DolphinDB Monte Carlo + PDE 工具实测
数据库·时序数据库·量化金融·dolphindb
淡海水4 小时前
07-06-源码-.NET Core GC的极致优化技术
unity·架构·c#·.netcore·gc·1024程序员节
泡海椒5 小时前
深度解析JQuick-SQL 逻辑计划到物理计划生成机制|分布式SQL原理
数据库·分布式·sql
恒知学术5 小时前
时间序列异常检测论文怎么查?我把 3 轮检索和筛选表写成了可复现流程
数据库·文献检索·谷歌学术
小豆庄5 小时前
视频脱敏:云端识别与本地推理的边界实测
数据库·yolo·自然语言处理·视觉检测·视频·设计规范·纹理贴图
wshzd5 小时前
LLM之Agent(120)|DeepSeek-Harness(二十七)Workflow 引擎与 Ralph 循环
前端·数据库·人工智能
l1t5 小时前
DeepSeek总结的DuckDB 2.0.0 中的隐藏亮点
大数据·数据库·duckdb
爱吃火鸡面呀5 小时前
MySQL、ClickHouse、Doris、Hive、Spark SQL、Flink SQL 选型对比:优点、缺点与面试话术
hive·mysql·clickhouse