MySQL—B+树构建

结合前面 student 表、聚簇索引 / 前缀二级索引 实例,讲解 B + 树构建规则、分步流程、节点分裂,配套可视化结构,适配考试 + 实操。

一、B + 树核心规则(InnoDB 标准,必背)

多路平衡查找树为基础,针对索引优化:

  1. 所有数据仅存于叶子节点 ,非叶子节点只存索引关键字 + 子节点指针,仅用来引路。
  2. 节点关键字有序排列,整棵树全局有序。
  3. 所有叶子节点用双向链表串联,支持范围查询。
  4. 非叶子节点关键字 = 下层子树的分界值
  5. 节点满了会节点分裂,向上更新父节点,保证树平衡。

InnoDB 索引页默认大小 16KB,一个节点可存放大量关键字,树层数极低(一般 2~4 层)。


二、以【聚簇索引】为例完整构建 B + 树

沿用示例表,主键 sid 作为排序键,数据:sid:1、2、3、4、5、6

1. 设定规则(简化演示)

为方便画图,约定:

  • 每个节点最多存放 3 个关键字
  • 超出容量触发节点分裂

2. 分步插入 & 构建过程

第 1 步:插入 1

树为空,新建叶子节点:

plaintext

复制代码
叶子节点:[1]

第 2 步:插入 2

直接追加到同一叶子节点(未满):

plaintext

复制代码
叶子节点:[1, 2]

第 3 步:插入 3

节点达到最大容量 3

plaintext

复制代码
叶子节点:[1, 2, 3]

第 4 步:插入 4 → 触发叶子节点分裂

原叶子已满,一分为二

  1. 原节点保留左半部分:[1, 2]
  2. 新建右侧叶子节点:[3, 4]
  3. 取中间值 3 上升,创建根非叶子节点存储分界值。

当前结构:

plaintext

复制代码
        根节点(非叶子)
            [3]
       ↙        ↘
叶子[1,2]    叶子[3,4]

第 5 步:插入 5

追加到右侧叶子 [3,4],节点满:

plaintext

复制代码
        [3]
   ↙        ↘
[1,2]    [3,4,5]

第 6 步:插入 6 → 再次分裂

右侧叶子已满,再次分裂:

  1. 拆分 [3,4,5] → 左[3,4]、右[5,6]
  2. 中间值 5 向上合并到根节点。

最终成型 B + 树(聚簇索引)

plaintext

复制代码
        根节点(非叶子)
        [3, 5]
   ↙       ↓        ↘
叶子[1,2] 叶子[3,4] 叶子[5,6]

补充说明

  1. 所有 sid 数据行 都保存在叶子节点中;
  2. 非叶子节点 [3,5] 只是分界值,不存完整数据;
  3. 三个叶子节点通过双向链表相连,有序排列。

三、以【前缀二级索引】构建 B + 树(sname 前 2 字符)

索引:sname(2),存储内容:前缀字符 + 主键 sid 数据前缀排序:(张三,1)、(张三,2)、(张小,3)、(李四,4)、(李磊,5)、(王五,6)

同样约定:单节点最多存 3 条索引项。

分步构建

  1. 依次插入 (张三,1)、(张三,2)、(张小,3)叶子节点存满:[(张三,1), (张三,2), (张小,3)]

  2. 插入第 4 条 (李四,4) → 叶子分裂

    • 左叶子:[(张三,1), (张三,2)]
    • 右叶子:[(张小,3), (李四,4)]
    • 中间分界值 张小 上升为根节点

plaintext

复制代码
      根节点 [张小]
   ↙          ↘
左叶子      右叶子
[张三,1]    [张小,3]
[张三,2]    [李四,4]
  1. 继续插入 (李磊,5)、(王五,6)右侧叶子填满后再次分裂,最终结构:

plaintext

复制代码
        根节点 [张小, 李磊]
    ↙        ↓         ↘
叶子组1    叶子组2     叶子组3
(张三,1)   (张小,3)    (李磊,5)
(张三,2)   (李四,4)    (王五,6)

二级索引 B + 树特点

  • 叶子:(前缀字符, 主键sid)无整行数据
  • 非叶子:仅分界前缀字符;
  • 查询后必须回表

四、节点分裂核心逻辑(考点)

  1. 向节点插入关键字,节点已满 → 触发分裂;
  2. 将当前节点数据从中间一分为二
  3. 中间位置的关键字向上提升到父节点
  4. 父节点如果也满,继续向上分裂,直到根节点;
  5. 根节点分裂 → 树层数 + 1

B + 树 自平衡,插入 / 删除后自动维护结构,不会变成斜树。


五、B + 树 与 B 树 构建区别(简答考点)

  1. B 树:所有节点(含非叶子)都存储数据 + 关键字;
  2. B + 树 :仅叶子节点存数据,非叶子只做索引分界;
  3. B + 树非叶子节点更小、能存放更多分界值,树层数更少、IO 更少;
  4. B + 树叶子链表,范围查询远优于 B 树。

六、考试标准简答题答案

1. B + 树构建过程

按照关键字大小升序依次插入节点;节点存满后从中间分裂,中间关键字上浮至父节点作为分界值;重复该过程直至所有数据插入完成。所有业务数据仅保存在叶子节点,非叶子节点只存储分界关键字用于检索,叶子节点通过双向链表串联,最终形成多路平衡 B + 树。

2. InnoDB 索引为什么选用 B + 树

B + 树非叶子节点不存储数据,节点容量大,树高度低,磁盘 IO 次数少;叶子节点有序链表,等值查询、范围查询效率高,非常适合数据库索引场景。


七、总结(串联之前知识点)

  1. 聚簇索引:以主键 为关键字构建 B + 树,叶子存整行数据
  2. 二级 / 前缀索引:以索引字段 为关键字构建 B + 树,叶子存索引值 + 主键
  3. 查找流程:二级索引 B + 树 → 拿到主键 → 回表 → 聚簇索引 B + 树 → 取完整数据;
  4. 构建核心:有序插入 + 节点分裂 + 分层存储。
相关推荐
飞将10 分钟前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils20 小时前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
Jim6002 天前
【吃透 MySQL InnoDB连载】第 1 章・解密线上数据库高频故障
mysql
GreatSQL2 天前
gt-checksum v4.0.0 新功能解读系列文章(4):SSL 加密连接——数据校验传输安全再升级
mysql
倔强的石头_2 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
云技纵横5 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
沉默王二5 天前
面试官:RAG 不用向量数据库,用 MySQL 硬扛?我:100 万向量不是很轻松?
mysql·面试·ai编程