问题
关系型数据库最核心的基础知识有哪些?如果只想建立正确心智模型,应该先抓住哪些主线?
回答
核心结论
关系型数据库的基础可以先抓五条主线:
- 事务:保证一组操作的整体性
- 隔离级别:处理并发读写之间的互相影响
- 锁:控制访问冲突
- 索引:提升查询效率
- MVCC:在并发读场景中减少锁冲突
先把这五条主线建立起来,后面的 Redo Log、Undo Log、Binlog、执行计划、慢 SQL 才更容易看懂。
1. 事务:为什么多条 SQL 要“绑在一起”
事务可以理解成一组要么全部成功、要么全部失败的操作。
最经典的例子是转账:
- A 扣钱
- B 加钱
如果只成功了一半,数据就错了,所以需要事务把这些步骤视为一个整体。
ACID
| 特性 | 含义 | 直观理解 |
|---|---|---|
| Atomicity | 原子性 | 要么全成,要么全回滚 |
| Consistency | 一致性 | 事务前后满足业务约束 |
| Isolation | 隔离性 | 并发事务互相影响要可控 |
| Durability | 持久性 | 提交成功后结果要能保住 |
2. 隔离级别:并发时到底允许看到什么
数据库不是只有你一个人在操作,所以要回答一个关键问题:
一个事务在执行时,是否应该看到别的事务尚未提交或刚刚提交的变化?
常见并发问题:
- 脏读:读到别人未提交的数据
- 不可重复读:同一事务两次读取同一行,结果不同
- 幻读:同一事务两次按条件查询,结果集条数发生变化
常见隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
| READ COMMITTED | 不会 | 可能 | 可能 |
| REPEATABLE READ | 不会 | 大多避免 | 依赖具体实现 |
| SERIALIZABLE | 不会 | 不会 | 不会 |
要注意两点:
- 这是逻辑层面的标准描述
- 不同数据库、不同存储引擎的实现细节并不完全一样
例如 MySQL InnoDB 默认是 REPEATABLE READ,并会结合 MVCC 与锁机制处理并发问题;但不要把它简单理解成“一句话彻底解决所有幻读”。
3. 锁:并发写入时怎么避免互相踩踏
锁的作用是让多个事务在访问同一批数据时保持秩序。
按读写语义看
| 锁 | 作用 |
|---|---|
| 共享锁(S) | 允许多个读者同时读取 |
| 排他锁(X) | 写入时独占资源 |
按策略看
| 策略 | 说明 |
|---|---|
| 悲观锁 | 先假设会冲突,提前加锁 |
| 乐观锁 | 先假设冲突少,提交时再检查版本 |
4. 索引:为什么查得快
索引可以理解成“帮数据库更快定位数据的目录”。
常见认识
| 概念 | 说明 |
|---|---|
| B+ 树索引 | 关系型数据库中非常常见,适合范围查询与排序 |
| 聚簇索引 | 数据和主键组织在一起(如 InnoDB 主键索引) |
| 二级索引 | 索引项里通常不直接包含整行数据,常需要回表 |
建索引时常记的三件事
- 联合索引要注意最左前缀原则
- 能用覆盖索引时,可以减少回表
- 不是所有条件都“天然索引失效”,要结合执行计划看
例如:
LIKE '%abc'- 对列做函数运算
- 隐式类型转换
这些都常导致索引利用变差;但像 IS NULL 是否走索引,不能一概而论,要结合数据库实现与数据分布判断。
5. MVCC:为什么很多读操作不用一直加锁
MVCC 可以理解成:
- 一行数据可能不只有“当前值”
- 数据库会保留一定的历史版本信息
- 事务根据自己的可见性规则读到合适的版本
它的目标是:
- 提高并发读性能
- 减少读写互相阻塞
在 MySQL InnoDB 里,MVCC 常和这些概念一起出现:
- Undo Log
- Read View
- 隐藏字段(如事务 ID)
五条主线怎么串起来
可以把数据库并发控制理解成下面这张图:
| 主线 | 解决什么问题 |
|---|---|
| 事务 | 一组操作如何保持整体正确 |
| 隔离级别 | 并发事务之间允许互相看到多少 |
| 锁 | 冲突时如何串行化访问 |
| 索引 | 如何更快找到数据 |
| MVCC | 如何减少读写冲突 |
三大日志分别做什么
如果进一步看 MySQL/InnoDB,最常出现的是这三类日志:
| 日志 | 主要作用 |
|---|---|
| Redo Log | 崩溃恢复,保证已提交修改可恢复 |
| Undo Log | 回滚事务,并支持 MVCC 历史版本 |
| Binlog | 主从复制、归档和恢复 |
一个容易记住的口诀是:
- Redo:记“改完后要怎么重做”
- Undo:记“出问题时怎么撤回”
- Binlog:记“这次操作要怎样对外同步和追溯”
学习顺序建议
如果你是第一次系统学数据库,建议按这个顺序:
- 事务和 ACID
- 隔离级别与并发问题
- 锁和 MVCC
- 索引与执行计划
- Redo / Undo / Binlog
这样不会一开始就被细节淹没。
一句话总结
关系型数据库的核心不是“会写 SQL”就够了,而是理解事务、并发控制和索引这套机制如何共同保证“又快又对”。
相关问题
- 为什么主键常建议自增或趋势递增? → 因为这通常更利于 B+ 树组织,减少页分裂与写入抖动。
- 回表是什么? → 先通过二级索引找到主键,再回到主键索引或数据页取完整数据。
- 隔离级别越高越好吗? → 不是,隔离越强通常并发能力越低,要按业务需求取平衡。
技术拓展
用“转账”串起整套知识
以转账为例:
- 事务保证“扣钱 + 加钱”要么一起成功,要么一起失败
- 隔离级别决定别的事务能否看到中间状态
- 锁避免多人同时改同一行时互相覆盖
- MVCC 让读操作不必总被写操作堵住
- Redo / Undo / Binlog 负责恢复、回滚和复制
如果能把这个例子想通,数据库基础就算真正入门了。