当前位置: 首页 > news >正文

根节点不存完整行数据!InnoDB B + 树「层级分工 + 索引定位」全拆解

根节点不存完整行数据!InnoDB B + 树「层级分工 + 索引定位」全拆解

很多第一次学习Mysql数据库索引的朋友都会弄错一个概念,那就是认为根节点是用来存完整行数据的,这往往是没有弄清楚InnoDB中B+树的底层结构所导致的。

InnoDB B + 树的根节点、非叶子节点,都绝对不存完整行数据,只有叶子节点才存完整行数据(聚集索引)。

非叶子节点(包括根节点)只存「索引键 + 子节点指针」,作用是快速定位叶子节点,不存业务数据。


接下来我会让大家彻底搞懂InnoDB B + 树的层级和索引的原理。

一、先彻底搞懂:B + 树每一层到底存什么?

我们以 InnoDB 的主键聚集索引为例,用一个 3 层 B + 树的结构:

首先我们要知道B+树依次分为根节点,中间节点,和叶子节点

其中根节点和中间节点可以统称为非叶子节点,即B+树就由非叶子节点和叶子节点所构成。

1. 层级 1:根节点(最顶层,非叶子节点)

  • 存储内容:只存「主键值 + 子节点(中间层)的页指针」

  • 作用:作为整个树的 “总目录”,根据查询的主键值,快速定位到中间层的对应节点

举个栗子:

根节点存:

(10, 页A指针)、(30, 页B指针)

它的意思是:

  • 主键 < 10 的数据,去页 A 找

  • 10 ≤ 主键 < 30 的数据,去页 B 找

  • 主键 ≥30 的数据,去页 C 找(省略)

2. 层级 2:中间节点(非叶子节点,树高 > 2 时存在)

  • 存储内容:同样只存「主键值 + 子节点(叶子层)的页指针」

  • 作用:作为 “二级目录”,从根节点定位到中间层后,再进一步定位到具体的叶子页

举个例子:

页 A(中间节点)存

(1, 页1指针)、(5, 页2指针)

意思是:

  • 主键 <5 的数据,去页 1 找

  • 主键 ≥5 的数据,去页 2 找

3. 层级 3:叶子节点(最底层)

  • 存储内容完整的行数据(所有列),并且所有叶子页用双向链表串联

  • 作用:真正存储业务数据,是查询的最终落脚点


二、核心问题:非叶子节点(根节点)怎么判断叶子节点存哪些数据?

1. 核心机制:「索引键的分隔值(Separator Key)」

非叶子节点的每一个索引键,本质是它右侧子树的「最小主键值」(也叫分隔键),用来划分数据范围。

  • 所有小于当前分隔键的数据,都在左侧子树

  • 所有大于等于当前分隔键的数据,都在右侧子树

2. 完整定位流程(以查询主键 = 6 为例)

  1. 根节点判断:根节点的分隔键是 10、30,6 < 10 → 进入左侧子树(页 A)

  2. 中间节点判断:页 A 的分隔键是 1、5,6 ≥5 → 进入右侧子树(页 2)

  3. 叶子节点定位:页 2 是叶子页,直接在页内按顺序找到主键 = 6 的完整行数据

3. 为什么用分隔键就能精准定位?

因为 InnoDB 的 B + 树有两个铁律

  1. 绝对有序:所有节点(包括非叶子、叶子)内的索引键,都严格按升序排列

  2. 范围划分严格:非叶子节点的分隔键,会把数据划分成互不重叠的连续区间,保证每一行数据只会出现在唯一的叶子页


三、举个完整的 3 层 B + 树实例,一眼看懂

假设我们有一个用户表,主键是user_id,插入了 1-20 号用户的数据,B + 树结构如下:

根节点(层 1)

分隔键(user_id)子节点页指针数据范围划分
7页 A 指针user_id <7 → 页 A
15页 B 指针7≤user_id <15 → 页 B
-页 C 指针user_id ≥15 → 页 C

中间节点(层 2,以页 A 为例)

分隔键(user_id)子节点页指针数据范围划分
3页 1 指针user_id <3 → 页 1
5页 2 指针3≤user_id <5 → 页 2
-页 3 指针user_id ≥5 → 页 3

叶子节点(层 3,以页 3 为例)

user_idnameage...(完整行数据)下一页指针
5张三20...页 4 指针
6李四21...页 4 指针
7王五22...页 4 指针

你看:根节点只存 7、15 两个分隔键,完全不存用户的 name、age 等完整数据;中间节点只存 3、5 两个分隔键,也不存完整数据;只有叶子页 3 里,才存了 5、6、7 号用户的完整行数据。


四、补充:为什么非叶子节点不存完整数据?

1. 核心原因:最大化扇出,降低树高

  • 非叶子节点如果存完整数据,一个 16KB 的页只能存十几行,树会变得 “又高又瘦”,查询需要几十次磁盘 IO,性能爆炸

  • 只存「索引键 + 指针」(总大小仅十几字节),一个 16KB 的页能存上千个索引项,树变得 “矮胖”,亿级数据也只需要 3-4 次 IO

2. 额外好处:减少内存占用

  • 根节点和上层非叶子节点,会被 InnoDB常驻内存(缓冲池),因为查询永远从根节点开始

  • 只存小体积的索引键 + 指针,内存占用极低,能让更多索引页常驻内存,进一步提升查询速度


五、面试高频考点:根节点会不会分裂?树高怎么变?

1. 根节点的分裂

根节点本质也是非叶子节点,当根节点存满了(16KB 页填满),同样会触发页分裂

  1. 申请一个新的根节点页

  2. 把原根节点的一半分隔键,迁移到新根节点

  3. 原根节点变成中间节点,树的高度 + 1

注意:根节点分裂是树长高的唯一方式,InnoDB 的 B + 树永远从根节点开始生长,不会从叶子层直接长高。

2. 树高的极限

  • InnoDB 的 B + 树高度,通常在3-4 层(千万 - 亿级数据),最多不会超过 5 层

  • 树高每增加 1 层,查询就多一次磁盘 IO,所以 InnoDB 的设计就是通过高扇出,把树高压到最低


六、最终总结

  1. 根节点 / 非叶子节点:只存「索引键 + 子节点指针」,绝对不存完整行数据

  2. 定位逻辑:通过「分隔键」划分数据范围,按层级快速定位到唯一的叶子页

  3. 叶子节点:唯一存储完整行数据的层级,所有数据按主键有序排列

  4. 设计本质:用 “目录式” 的非叶子节点,最大化扇出、降低树高,实现海量数据下的高效查询

这是前置内容,仅做一些参考学习,后面会陆续讲解数据库索引相关的知识,欢迎读者大佬指点批评

http://www.jsqmd.com/news/655783/

相关文章:

  • 为什么92%的AI编程工具在中文+英文混合场景下生成失效?——全链路多语言上下文建模白皮书首发
  • 2026年3月不锈钢方棒品牌哪个好,不锈钢光圆/不锈钢黑棒/锻棒/不锈钢方棒/不锈钢六角棒,不锈钢方棒品牌找哪家 - 品牌推荐师
  • VRC Gesture Manager实战指南:从动画预览到专业调试的全流程解析
  • 若依(RuoYi)项目Excel导出慢?别急着加服务器,先看看这个字典缓存优化方案
  • Docker部署Mysql
  • SITS2026白皮书技术内核拆解:从AST重写引擎到语义沙盒机制,为什么说这是首个可审计、可回滚的生成式编码标准?
  • 终极开源ITOM平台部署指南:15分钟快速搭建NeatLogic运维管理平台
  • 为什么83%的AI生成代码未通过OWASP ASVS 4.0?智能代码生成安全风险评估的4个致命盲区与合规落地路线图
  • 信捷HMI与西门子S7-1200的TCP通信实战:从配置到抓包全解析
  • 从手机修图到工业检测:深入浅出聊聊直方图均衡(HE/AHE/CLAHE)到底该怎么选
  • Winhance中文版:构建Windows系统优化的终极解决方案
  • 基于Matlab/Simulink的纯电动汽车仿真模型(包括电池、电机等模块)
  • SAP CO-PA数据传送实战:销售开票与FI/MM记账的配置避坑指南(KEKF/KE4I/KEI2)
  • 2026年华东华中热力工程保温管道系统:蒸汽直埋、预制管网与节能技术全景(含官方联系方式) - 精选优质企业推荐官
  • 细胞因子聚焦:白细胞介素家族中的抗炎“卫士”
  • 分期乐微信立减金回收靠谱吗?深度解析回收流程 - 团团收购物卡回收
  • 从 “能用” 到 “好用”:集之互动以工程化服务提升 AI 短剧品质
  • 云原生环境中的边缘计算:从K3s到生产实践
  • 治疗用免疫细胞体外培养时如何兼顾T细胞扩增与TCM表型维持【曼博生物官方提供Sexton hPL】 - 上海曼博生物
  • 【头部金融科技实战复盘】:如何将AI生成代码上线缺陷率压至0.08‰——质量保障五阶跃迁路径
  • 告别手动清理!用这3款免费工具一键彻底卸载Unity(附注册表备份教程)
  • MAA明日方舟助手:开源游戏自动化框架的技术深度解析
  • openGauss JDBC 驱动源码调试实战:从环境配置到断点追踪
  • CCD与CMOS技术对比
  • OSI七层模型
  • FreeCAD绘图尺寸标注实战:从工程图新手到标注高手
  • Windows系统优化终极指南:如何用开源工具彻底解决C盘爆红问题
  • 2026年华东、华中热力管网系统建设与蒸汽直埋保温管解决方案 - 精选优质企业推荐官
  • SOLIDWORKS 放样真不难!沉浸式教学,一遍就会
  • 思源宋体CN终极指南:7种字重免费开源字体如何彻底改变你的中文排版