一、核心定义与本质(基础概念)
- 资料:
https://pan.quark.cn/s/43d906ddfa1b、https://pan.quark.cn/s/90ad8fba8347、https://pan.quark.cn/s/d9d72152d3cf
1. B树(平衡多路查找树)
- 定义 :一棵 m 阶 B 树(m≥2)是满足以下条件的平衡多路查找树:
- 每个节点最多有 m 个子节点(m 阶即最大子节点数);
- 根节点最少 1 个子节点,非根节点最少 ⌈m/2⌉ 个子节点;
- 每个节点的关键字个数 = 子节点个数 - 1,关键字按升序排列;
- 所有叶子节点在同一层,无空指针。
- 本质:平衡的"多路"查找树(区别于二叉树的"二路"),核心解决"磁盘I/O高效读取"问题(减少树的高度,降低磁盘访问次数)。
2. B+树(B树的优化变种)
- 定义 :基于 m 阶 B 树扩展,满足以下特性:
- 非叶子节点仅存关键字和子节点指针,不存数据(数据仅在叶子节点);
- 叶子节点关键字数量 = 子节点个数(与 B 树不同),且按顺序链表连接;
- 非叶子节点的关键字是叶子节点的索引(即某个子树的最小/最大关键字);
- 所有数据都在叶子节点,且叶子节点构成有序链表。
- 本质:"索引与数据分离"的优化结构,更适配数据库、文件系统的查询场景。
3. B*树(B+树的进一步优化)
- 定义 :基于 m 阶 B+ 树扩展,核心优化节点填充率:
- 非叶子节点的最小子节点数 = ⌈2m/3⌉(B 树是 ⌈m/2⌉,填充率更高);
- 叶子节点和非叶子节点都采用链表连接(B+ 树仅叶子节点链表);
- 其余特性与 B+ 树一致(数据在叶子节点,索引分离)。
- 本质:高填充率的 B+ 树变种,减少节点分裂次数,提升空间利用率。
二、核心区别对比(表格结构化)
| 特性 | B树 | B+树 | B*树 |
|---|---|---|---|
| 数据存储位置 | 所有节点(根、非叶、叶) | 仅叶子节点 | 仅叶子节点 |
| 非叶节点存储内容 | 关键字 + 数据 + 子节点指针 | 关键字 + 子节点指针(无数据) | 关键字 + 子节点指针(无数据) |
| 叶子节点特性 | 无链表连接,无序 | 有序链表连接 | 有序链表连接(非叶也链表) |
| 最小子节点数(m阶) | ⌈m/2⌉ | ⌈m/2⌉ | ⌈2m/3⌉ |
| 节点填充率 | 较低(50% 左右) | 中等 | 较高(66% 左右) |
| 查找效率 | 不稳定(取决于数据位置) | 稳定(必查叶子节点) | 稳定(必查叶子节点) |
| 范围查询支持 | 需回溯,效率低 | 直接遍历叶子链表,高效 | 直接遍历链表,效率更高 |
| 插入/删除效率 | 易分裂,效率一般 | 分裂频率低于 B 树 | 分裂频率最低(填充率高) |
三、适用场景(由浅入深,结合实际应用)
1. B树的适用场景
- 核心场景:内存中的查找结构(无需频繁磁盘I/O);
- 具体例子:
- 数据库中的索引缓存(内存中临时存储,快速查询);
- 小型数据集的多路查找(如内存中的字典、缓存)。
- 原因:数据可存在非叶节点,查询可能提前终止,内存中无I/O开销,效率较高。
2. B+树的适用场景
- 核心场景:磁盘存储的数据库/文件系统(MySQL、Oracle 索引,NTFS 文件系统);
- 具体例子:
- MySQL 主键索引(聚簇索引)、二级索引;
- 传统关系型数据库的核心索引结构。
- 原因:
- 索引与数据分离,非叶节点体积小,单次磁盘I/O可加载更多索引,减少I/O次数;
- 范围查询高效(遍历叶子链表),符合数据库高频范围查询需求;
- 查找稳定,所有查询都到叶子节点,便于优化。
3. B*树的适用场景
- 核心场景:高并发、大数据量的磁盘存储系统(需要更高空间利用率);
- 具体例子:
- 部分分布式数据库索引(如 MongoDB 早期版本);
- 大型文件系统(如 EXT4 的扩展索引)。
- 原因:
- 填充率高达 66%,节点分裂次数少,减少磁盘I/O和存储空间开销;
- 非叶节点也有链表连接,跨节点查询更高效,适配分布式场景。
四、底层原理延伸(进阶理解)
1. 为什么数据库不用 B 树?
- 磁盘I/O成本:B树非叶节点存数据,导致节点体积大,单次I/O只能加载少量索引,树的高度更高(I/O次数多);
- 范围查询:B树需回溯父节点,而B+树叶子链表直接遍历,效率差一个数量级;
- 数据一致性:B树数据分散在所有节点,插入删除易导致节点分裂/合并,维护成本高。
2. B+树 vs B*树:为什么大部分数据库选 B+树?
- B*树的高填充率是双刃剑:
- 优点:减少分裂,空间利用率高;
- 缺点:节点合并/分裂时,需要调整的子节点更多(因为最小子节点数更高),高并发场景下锁竞争更激烈;
- 数据库的权衡:大部分场景下,B+树的"平衡效率"优于 B*树的"空间效率",且实现更简单,因此成为主流。
3. 核心设计思想:为什么都是"多路"树?
- 二叉树的问题:高度过高(n 个节点,高度 O(log₂n)),磁盘I/O次数多(每次I/O只能读一个节点);
- 多路树的优势:m 阶树的高度 O(logₘn),m 越大,高度越低(如 m=1000 时,10亿数据的高度仅 3 层),I/O次数极少(3次即可查询到数据);
- 本质:用"多路"降低树高,适配磁盘I/O的"块存储"特性(一次I/O读取一个磁盘块,可容纳多个关键字)。
五、学习路径建议(构建知识体系)
- 基础阶段:先掌握 B 树的插入、删除、查找逻辑(理解"平衡多路"的核心);
- 进阶阶段:对比 B 树和 B+ 树的差异,重点理解"数据与索引分离"的设计思路;
- 应用阶段:结合数据库索引(如 MySQL 聚簇索引、非聚簇索引),实际分析 B+ 树的应用;
- 拓展阶段:了解 B*树的优化点,以及红黑树、哈希表与三者的适用场景对比(如哈希表不支持范围查询,红黑树适用于内存小数据集)。