🥰个人主页:会编程的土豆(欢迎来访)
💎作者简介:后端学习者
✨那些你一个人走过的夜路,终将化作照亮未 来的光



一、执行一条 SQL 请求的过程
1. 大白话版
① 先看看你是谁
确认:账号对不对、有没有权限查这张表。
→ 像进网吧要刷卡。
② 看看你这句话写对没有
检查:单词对不对、语法通不通。
写错了直接报错,后面都不干了。
→ 像老师先看你作文有没有病句。
③ 想想怎么查最快
比如有索引就走索引,没有就一张张翻。
→ 像找书:有目录就翻目录,没目录就整架翻。
④ 真的去拿数据,再给你
从表里把结果捞出来,返回到你屏幕上。
→ 像图书馆员把书递到你手里。
2. 分步说明(对应 MySQL 内部组件)
① 连接器
- 负责跟客户端建立连接(账号、密码、权限)
- 连接成功后,你的会话权限就定了
② 查询缓存(了解即可)
- MySQL 5.7 及以前:先看有没有一模一样的查询结果缓存
- MySQL 8.0 已去掉,现在可以当这段不存在
③ 分析器(Parser)
做两件事:
- 词法分析 :把
select、from、表名、字段名拆成一个个「单词」 - 语法分析:看语句结构合不合法
写错了会在这里报错,例如:
You have an error in your SQL syntax...
④ 优化器(Optimizer)
决定怎么执行最快,例如:
- 有多个索引,用哪个?
- 多表连接,先连哪张表?
- 要不要改写 SQL?
同一句 SQL,优化器可能选出不同执行计划。
⑤ 执行器(Executor)
- 先判断你有没有操作这张表的权限
- 再按优化器给出的计划,调用存储引擎接口去取数/改数
⑥ 存储引擎(如 InnoDB)
- 真正负责数据存放、索引、事务、锁
- 从内存缓冲池或磁盘读出数据,再交回执行器
二、存储引擎
1. 是什么
存储引擎 = MySQL 里「表的数据到底怎么存、怎么锁、安不安全」的那一层。
- MySQL:前台,听懂你的 SQL
- 存储引擎:后台仓库,真正把数据落到磁盘
2. 为什么需要存储引擎
存数据时可以有不同规矩,例如:
- 要不要支持事务(一包操作全成或全取消)
- 多人同时改时怎么互斥
- 断电后能不能恢复
MySQL 允许每张表选一套规矩 → 这套规矩就叫存储引擎。
3. 和表的关系
数据库 chatroom
└── 表 newtable ──绑定──► 某个存储引擎(现在多半是 InnoDB)
└── 表 users ──绑定──► 某个存储引擎
你写 INSERT / SELECT 时,感觉在操作表;
实际写入/读取,由这张表绑定的引擎完成。
4. InnoDB(默认、首选)
现在新建表,默认基本都是 InnoDB。

结论:业务表优先 InnoDB;搞不清就用默认的。
执行流程示意:
你:INSERT INTO newtable ...
↓
MySQL(前台)收到 SQL
↓
发现 newtable 使用 InnoDB
↓
InnoDB(仓库)真正写入磁盘
- SQL 写法大多一样
- 事务能不能做、并发好不好,跟引擎有关
怎么查看引擎:
SHOW CREATE TABLE newtable;
三、MySQL 事务
1. 是什么
事务 = 把多步数据库操作打包成「一件事」:要么全部成功,要么全部失败(回滚)。
2. 为什么需要事务(转账例子)
假设 A 给 B 转 100 元,要两步:
- A 账户减 100
- B 账户加 100
如果第 1 步成功、第 2 步失败:
钱从 A 没了,B 也没收到 → 事故。
有了事务:
- 两步都成功 → 一起生效(提交)
- 任何一步失败 → 一起取消(回滚)
钱不会平白消失。
3. 和存储引擎的关系
想用事务 → 表要用 InnoDB(现在默认就是)。
4. 常见操作

- 开启:BEGIN; / START TRANSACTION;
- 提交:COMMIT;
- 回滚:ROLLBACK;
示例:
BEGIN;
UPDATE account SET money = money - 100 WHERE name = 'A';
UPDATE account SET money = money + 100 WHERE name = 'B';
COMMIT; -- 两步都 OK,一起生效
-- 若中途发现问题,改用:ROLLBACK;
注意:
- COMMIT 之前,别的连接有时还看不到你的改动(取决于隔离级别;零基础先记:没提交就不算最终定案)
- COMMIT 之后,一般就定了,不能再靠这次事务的 ROLLBACK 反悔
5. 没有事务时会怎样
每条 SQL 常常自动立刻生效(自动提交)。
- 适合:单条无关痛痒的插入/查询
- 不适合:必须「几步绑在一起」的业务(转账、下单扣库存、创建订单+扣积分等)
6. 业务里的常见写法
开启事务
→ 改表 A
→ 改表 B
→ 都成功就 Commit
→ 有错就 Rollback
四、锁
1. 是什么
锁 = 防止多人同时改同一份数据时互相踩脚的「占用规则」。
2. 为什么需要锁(抢厕所比喻)
一张表里某一行,像一间厕所:
- 没锁:两个人同时冲进去,可能乱套
- 有锁:一个人进去时门锁上,另一个人在外面等
数据库也一样:
两个请求同时改同一行余额,没有锁,可能都读到旧值再写回去 → 钱算错。
- 事务解决:多步要同生共死
- 锁解决:多人同时来时别互相覆盖
两者经常一起出现,但不是同一个东西。
3. 先分清两种范围
① 行锁(锁一行)------ InnoDB 常用
- 只锁你改的那一行
- 别人改另一行,常常还能继续
- 适合:高并发业务(聊天、下单、用户表)
② 表锁(锁整张表)------ 较粗暴
- 一张表被锁,别人对这张表的很多操作都可能要等
- 像整栋楼封了,不只锁一间厕所
- MyISAM 老引擎偏表锁;InnoDB 日常更偏向行锁(这也是为啥推荐 InnoDB)

4. 再分清两种态度(读和写)
① 共享锁(读锁,S 锁)------「可以一起看」
- 多人可以同时读
- 有人拿着读锁时,通常不让别人随便改
- 像图书馆:很多人能同时看书,但不能同时撕页改内容
② 排他锁(写锁,X 锁)------「我改的时候别人别乱动」
- 有人在写,别人既不好随便写,读有时也要等(看具体策略)
- UPDATE / DELETE 时,InnoDB 往往会给涉及的行加写锁
口诀:
- 读锁:大家一起看可以
- 写锁:我改的时候请回避
5. 结合例子理解
执行:
UPDATE newtable SET age = 99 WHERE id = 3;
在 InnoDB 里大致会:
- 找到 id = 3 那一行
- 给这行加写锁(排他)
- 改完,事务提交后,锁再放开
- 别人同时改 id = 4 → 往往各改各的
- 别人同时也改 id = 3 → 后到的可能要等
你平时不一定手写 LOCK,引擎经常自动加锁。
6. 等待与死锁
① 正常等待
A 锁着某行还没提交,B 也要改同一行 → B 先等一会儿。
A COMMIT / ROLLBACK 后,B 继续。
② 死锁
A 锁了行 1,想要行 2
B 锁了行 2,想要行 1
互相等 → 死锁
MySQL 常会干掉其中一个事务,报错让你重试。
业务上:保持加锁顺序一致、事务尽量短,能少很多死锁。
7. 引擎、事务、锁怎么串起来
InnoDB(引擎)
└── 支持行锁 + 事务
└── 事务里的 UPDATE/DELETE 等
└── 自动给相关行加锁
└── COMMIT/ROLLBACK 后释放锁
三句话串记:
- 引擎:InnoDB 才有靠谱的行锁 + 事务
- 事务:多步打包
- 锁:打包期间别让别人把同一行改乱