← 返回题目列表

什么是 B+ 树?它和 B 树的核心区别是什么?

高频 中等 第 3 / 25 题 更新于 2026/07/28
B+树B树索引

简化版

B+ 树是 B 树的改进版,专为数据库索引优化。三个核心区别:① 只有叶子节点存数据,内部节点只存关键字(当索引路标),不存数据;② 所有数据都在叶子层,内部节点的关键字是叶子的「索引副本」;③ 叶子节点用指针连成一条有序链表。这三点让 B+ 树内部节点能容纳更多关键字(树更矮)、且范围查询/排序极快(顺着叶子链表扫)。

详细版

维度B 树B+ 树
数据存在哪每个节点(含内部节点)都存数据只有叶子节点存数据
内部节点作用存关键字 + 数据只存关键字(索引),不存数据
关键字分布每个关键字只出现一次内部节点的关键字在叶子层重复出现(是索引)
叶子节点各自独立用指针连成有序链表
范围查询需要中序遍历、回溯顺着叶子链表扫,极快
查询稳定性可能内部节点就命中(快慢不一)每次都走到叶子(路径等长,稳定)

完整版教学

一、B+ 树的三大改造

B+ 树在 B 树基础上做了三个关键改动,每个都为了「更适合磁盘索引」:

  1. 数据全部下沉到叶子:B 树的内部节点既存关键字又存数据;B+ 树的内部节点只存关键字(当路标),真正的数据(或数据行指针)全部放在叶子节点。
  2. 内部关键字是叶子的索引副本:因为数据都在叶子,内部节点的每个关键字只是「用来指路的分界值」,它会在叶子层再次出现。所以 B+ 树的关键字有冗余(内部一份、叶子一份),但换来了纯粹的「索引层 + 数据层」分离。
  3. 叶子连成有序链表:所有叶子节点从左到右用指针串起来,形成一条覆盖全部数据的有序链表。

二、为什么「内部节点不存数据」是关键优化

这是 B+ 树最重要的优势来源。磁盘按页读取,一个节点 = 一页(如 16KB)。

  • B 树:内部节点里每个关键字都跟着数据,一页装不了几个关键字 → 扇出小 → 树高。
  • B+ 树:内部节点只有关键字(几字节)没有数据,同样一页能装下多得多的关键字 → 扇出大得多 → 树更矮 → 磁盘 IO 更少。

也就是说,把数据从内部节点「赶」到叶子,腾出的空间让内部节点变成了「纯索引」,扇出暴涨,树被压得更矮。这是 B+ 树比 B 树更适合做索引的首要原因。

三、为什么叶子链表是「杀手锏」

B 树做范围查询(如「查 10 到 50 之间所有值」)很别扭:要中序遍历,在树里上上下下地回溯。

B+ 树的叶子是有序链表:先查到范围起点 10 所在的叶子,然后顺着链表指针一路向右扫,直到超过 50 为止——完全不用回树里绕。范围查询、排序、ORDER BY、分页,本质都是「扫叶子链表」,又快又顺(还是顺序 IO)。这是 B+ 树在数据库里无可替代的能力。

四、查询稳定性

  • B 树:一个关键字可能在很浅的内部节点就命中,也可能要走到叶子,查询快慢不一。
  • B+ 树:数据全在叶子,任何查询都要走到叶子层,路径长度完全一致。这让查询延迟非常稳定、可预测,对数据库的性能保障很重要。

五、代价:关键字冗余

B+ 树的内部节点关键字在叶子层重复出现,有一定空间冗余。但这点冗余相比它带来的好处(扇出大、范围快、稳定)微不足道——而且内部节点只存关键字本来就很小。所以工程上普遍认为这是笔非常划算的交易。

六、常见误区与追问

考点正确口径
B 树内部节点和叶子都可存数据
B+ 树数据只在叶子,内部节点只导航
范围查询B+ 树叶子链表更适合顺序扫描
B+ tree:
internal: keys + child pointers
leaf: keys + row pointers/data
leaf.next -> next leaf

B+ 树把内部节点变成纯目录,把所有数据集中到叶子层。

  • 误区:B+ 树只是 B 树多一个加号。 B+ 树改变了数据存放位置,并增加叶子链表,范围查询能力明显不同。
  • 误区:内部节点不存数据会浪费空间。 恰恰相反,内部节点更小,扇出更大,树高更低。
  • 误区:B+ 树查找一定比 B 树少走层数。 B 树可能在内部节点命中数据;B+ 树通常都走到叶子,但查询路径更稳定。
  • 追问:为什么数据库索引偏爱 B+ 树? 它树矮、范围查询强、叶子顺序扫描友好,非常符合磁盘页和区间查询。
  • 追问:关键字冗余是什么? 内部节点保存的 key 也会在叶子层出现,换来更高扇出和统一叶子数据层。
  • 追问:B+ 树叶子节点存什么? 聚簇索引叶子存整行数据,二级索引叶子通常存索引列和主键值。

七、加强记忆

B+ 树是 B 树的索引优化版,三大区别:① 只有叶子存数据,内部节点只存关键字(当路标);② 数据全在叶子层,内部关键字是叶子的索引副本(有冗余);③ 叶子连成有序链表。前两点让内部节点扇出更大、树更矮、IO 更少;叶子链表让范围查询/排序只需顺序扫叶子;数据全在叶子还让查询延迟稳定。这就是数据库索引选 B+ 树的根本。