← 返回题目列表

B* 树为什么要求节点更高填充率?它的分裂策略和 B 树有什么不同?

中等 第 22 / 25 题 更新于 2026/07/30
B*树B树分裂策略填充率

简化版

B* 树是 B 树家族的变体,通常要求节点至少约 2/3 满,而不是 B 树常见的至少半满。插入溢出时,B* 树会优先和兄弟节点重新分配;兄弟也满时,才把两个满节点和新 key 分裂成三个节点,从而提高空间利用率。

详细版

B 树节点满了通常直接分裂成两个节点,分裂后每个节点大约半满。B* 树为了提高页利用率,引入兄弟再分配和 2-to-3 split:

  1. 当前节点满;
  2. 先看相邻兄弟是否有空间;
  3. 若兄弟有空间,把 key 在当前节点、父分隔 key、兄弟之间重新分配;
  4. 若兄弟也满,把两个节点加上新 key 分成三个节点;
  5. 父节点插入新的分隔 key。

这样节点最低填充率可以提高到约 2/3,树更紧凑,空间利用率更好,但实现比普通 B 树分裂复杂。

完整版教学

一、B* 树想解决 B 树的什么问题

B 树分裂后两个节点通常各半满。这样简单,但空间利用率可能不高:大量页只有一半左右数据,索引文件更大,缓存效率也会下降。B* 树的目标是提高节点填充率,让每个页尽量更满。

在磁盘页作为节点的场景下,页利用率非常重要。一个页装得越满,同样数据需要的页越少,缓存和 I/O 压力越低。B* 树就是在分裂策略上更节省空间。

记忆钩子:B 树满了就一分为二,B* 树先找兄弟挤一挤,实在挤不下再二变三。

二、普通 B 树分裂为什么可能只有半满

普通 B 树节点满后,把中间 key 上提,左右两边分成两个节点。若一个节点最多放 5 个 key,插入后临时有 6 个 key,分裂成两个节点后可能各 2 到 3 个 key。填充率大约在 50% 附近。

[10 20 30 40 50] 插入 35
临时: [10 20 30 35 40 50]
分裂: [10 20] 30 [35 40 50]

这种策略实现清晰,但没有充分利用兄弟页可能还有空位的事实。

三、B* 树的再分配怎么做

当当前节点满时,B* 树会先检查相邻兄弟。如果兄弟没满,就把当前节点、父节点分隔 key、兄弟节点中的 key 合在一起重新分配,让两个节点都保持较高填充率,同时更新父分隔 key。

例如两个兄弟页容量都是 6:

左页: [10 20 30 40 50 60]  已满
右页: [80 90]              未满
插入 55 后,可把部分 key 移到右页,而不是立刻新建页

这样避免了一次页分裂,减少父节点更新,也提高页利用率。

四、两个满节点为什么分成三个

如果当前节点和兄弟都满,就把两个满节点、父分隔 key、新插入 key 合并后分成三个节点。两个满节点容量合计是 2m,加上新 key 和分隔信息后分成三个节点,每个节点大约 2/3 满。

2 个满页 + 1 个新 key  ->  3 个较满页
填充率约从 1/2 提升到 2/3

这就是 B* 树比普通 B 树空间利用率更高的核心。代价是分裂不再只看一个节点,还要协调兄弟和父节点。

五、B* 树和 B+ 树是什么关系

B* 树和 B+ 树关注点不同。B+ 树强调所有数据在叶子、叶子链表支持范围查询;B* 树强调更高节点填充率和兄弟再分配。实际系统可能组合多种思想,但教材里它们是 B 树家族的不同变体。

结构重点常见特征
B 树多路平衡查找内部节点可存数据
B+ 树范围查询和磁盘索引数据在叶子,叶子链表
B* 树提高空间利用率兄弟再分配,2-to-3 split

面试时不要把 B* 树简单说成 B+ 树的另一个名字,它强调的是分裂和填充率策略。

六、为什么工程里不一定总讲 B* 树

B* 树提高空间利用率,但实现更复杂。现代数据库存储引擎还会结合填充因子、页分裂策略、后台整理、压缩、MVCC 等机制综合优化。很多面试只要求理解 B/B+ 树,B* 树属于加分扩展。

如果被问到 B* 树,重点答出「至少 2/3 满」「先兄弟再分配」「两个满节点分成三个」就足够清晰。不要把它扩展成完全不同的索引模型。

七、常见误区与追问

  • 误区:B星树就是 B+ 树。 B* 树主要强调更高填充率和分裂策略,B+ 树强调叶子存数据和链表。
  • 追问:为什么最低填充率能到约 2/3? 两个满节点加新 key 分成三个节点,平均每个约三分之二满。
  • 误区:节点满了必须马上一分为二。 B* 树会先尝试和兄弟重新分配。
  • 追问:B星树代价是什么? 实现更复杂,分裂要协调兄弟和父节点。
  • 误区:填充率越高越没有缺点。 太满会增加后续插入分裂概率,工程上仍需平衡。
  • 追问:B星树为什么要先看兄弟节点? 因为兄弟有空位时重新分配比新增页更省空间,也能减少父节点结构变化。
  • 误区:B星树能避免所有页分裂。 它只能延后和减少分裂;兄弟也满时仍然需要 2-to-3 split。

八、加强记忆

B* 树可以记成「更抠空间的 B 树」。普通 B 树满了就分裂成两个半满节点;B* 树先找兄弟借空间,兄弟也满时再把两个节点分成三个,让页保持约 2/3 以上填充。它不是 B+ 树的同义词,而是 B 树家族里围绕填充率和分裂策略的一种改进。