跳转至

MySQL 存储原理相关问题

一、InnoDB vs MyISAM

InnoDB MyISAM
事务
外键
锁粒度 行锁 表锁
MVCC
主键 聚簇索引 非聚簇
崩溃恢复 ✅(redo log)

MySQL 5.5 之后默认 InnoDB。

二、聚簇索引与非聚簇索引

聚簇索引(Clustered Index)

InnoDB 的主键索引就是聚簇索引,叶子节点直接存整行数据。一张表只有一个聚簇索引。

如果没定义主键,InnoDB 会: 1. 选第一个非空唯一索引。 2. 都没有,自动生成一个 6 字节的隐藏主键。

非聚簇索引(Secondary Index / 二级索引)

叶子节点存主键值,不是行地址。

通过二级索引查完整行:

  1. 在二级索引找到主键值。
  2. 回到聚簇索引取整行(回表)。

如果二级索引已经包含要查的列(覆盖索引),就不用回表。

三、B+ 树为什么适合做索引

与二叉树、B 树、Hash 对比:

结构 特点
二叉树 树太高,IO 次数多
B 树 非叶子节点也存数据,单节点能放的 key 少
B+ 树 非叶子节点只存 key,单节点放更多 key,树更矮;叶子节点链表相连,范围查询快
Hash 等值查询 O(1),但不支持范围、排序

InnoDB 的 B+ 树通常 3~4 层就能支撑千万级数据,查询一次最多 3~4 次磁盘 IO。

四、页(Page)

InnoDB 最小存储单位是 ,默认 16KB。一个页内有多条记录,按主键有序排列。

  • 查询时按页加载到 Buffer Pool。
  • 页内用二分查找。
  • 页之间用双向链表。

五、Redo Log 与 Undo Log

Redo Log(重做日志)

  • 保证事务持久性(Durability)。
  • WAL(Write-Ahead Logging):先写 redo log,再写数据页。
  • crash-safe:宕机后用 redo log 重放。

Undo Log(回滚日志)

  • 保证原子性(Atomicity)。
  • 记录修改前的旧值,用于回滚和 MVCC。

Binlog(归档日志)

  • Server 层日志,记录所有变更。
  • 主从复制、数据恢复用。

高频追问

  • 为什么 InnoDB 推荐自增主键?B+ 树按主键顺序插入,避免页分裂;UUID 主键是无序的,导致页分裂频繁。
  • 什么是页分裂?插入新记录时页满了,申请新页,把一半数据移过去。