MySQL--B+树

扇出为n的n阶B树:每个节点最多存储n-1个key,n个指针 扇出为n的n阶B树:每个节点最多存储n-1个索引key,n个指针

B树(B-Tree)和B+树(B+ Tree)都是平衡的多路搜索树,常用于数据库和文件系统。

1、B树和B+树的区别

  • 数据存储位置

    • B树:数据(键值对)可以存储在内部节点(非叶子节点)和叶子节点上。
    • B+树 :数据存储在叶子节点上。内部节点仅存储用于导航的索引键(Key)和指向子节点的指针。
  • 叶子节点链接

    • B树:叶子节点之间没有直接的链接。
    • B+树:所有叶子节点通过指针形成一个有序的双向链表。这使得范围查询(Range Query)非常高效,只需遍历叶子节点链表即可。
  • 查询效率

    • B树:查找效率不稳定。查找一个存在的键,可能在内部节点就命中,也可能需要查到叶子节点,路径长度不固定。
    • B+树:查找效率稳定。任何查找都必须从根节点走到叶子节点,路径长度固定(树的高度),时间复杂度稳定。
  • 空间利用率与扇出

    • B树:由于内部节点也存储数据,每个节点能存储的键/指针对数量相对较少,导致树的"扇出"(每个节点的子节点数)较小,树的高度相对较高。
    • B+树:内部节点只存键和指针,不存数据,因此可以容纳更多的键/指针对,扇出更大,树的高度更低。在相同数据量下,B+树通常比B树矮,意味着查询时需要的磁盘I/O次数更少。
  • 范围查询效率

    • B树:进行范围查询时,需要多次从根节点开始查找,效率较低。
    • B+树:得益于叶子节点的链表结构,范围查询一旦定位到起始键,就可以顺序遍历链表,非常高效。

2、MySQL(InnoDB引擎)为什么选择B+树?

MySQL的InnoDB存储引擎选择B+树作为其索引结构(尤其是聚簇索引和二级索引),主要原因如下:

  • 高效的范围查询 : 这是最主要的原因之一。数据库应用中范围查询(如 WHERE id BETWEEN 10 AND 100)非常普遍。B+树的叶子节点链表结构使得这类查询只需一次定位起始点,然后顺序扫描即可,性能极佳。
  • 稳定的查询性能: B+树的所有查询(无论是点查还是范围查)最终都落在叶子节点,路径长度固定,性能稳定可预测。
  • 更高的扇出和更低的树高: 由于内部节点不存储数据行,可以存储更多的索引键和指针,使得B+树的"扇出"更大。在数据量大的情况下,B+树比B树更矮。这意味着在进行索引查找时,需要的磁盘I/O次数更少(通常只需3-4次I/O就能定位到数据),极大提升了查询效率。磁盘I/O是数据库性能的关键瓶颈,减少I/O至关重要。
  • 全节点扫描效率高: 当需要全表扫描或全索引扫描时,B+树可以直接遍历叶子节点的链表,而不需要像B树那样进行复杂的树遍历,效率更高。
  • 更适合磁盘存储特性: B+树的设计更符合磁盘顺序读取的特性。叶子节点的链表结构有利于顺序访问,而内部节点的高扇出减少了随机I/O的次数。

虽然B树在某些特定的点查场景下可能有优势(如果数据恰好在内部节点),但综合考虑范围查询、查询稳定性、I/O效率、全表扫描等数据库核心操作的需求,B+树在绝大多数场景下都优于B树。因此,MySQL(InnoDB)以及其他主流数据库系统(如Oracle, SQL Server)都选择B+树作为其索引结构的基础。

为什么不选择二叉树或红黑树作为索引数据结构?

二叉树 (Binary Tree)

定义: 二叉树是一种树形数据结构,其中每个节点最多有两个子节点,分别称为"左子节点"和"右子节点"。

二叉搜索树 (Binary Search Tree, BST) : 这是二叉树的一种重要特例,具有以下性质:

  • 对于任意一个节点,其左子树中的所有节点的值都小于该节点的值。
  • 对于任意一个节点,其右子树中的所有节点的值都大于该节点的值。
  • 左右子树也分别是二叉搜索树。

优点

  • 结构简单,易于理解和实现。
  • 在理想情况下(树是平衡的),查找、插入、删除的时间复杂度为 O(log n)。

缺点

  • 最大的问题:可能退化成链表。 如果插入的数据是有序的(例如,1, 2, 3, 4, 5),二叉搜索树会退化成一个单链表,其高度变为 n,此时查找、插入、删除的时间复杂度退化为 O(n),失去了树的优势。
  • 不适合磁盘存储:二叉树每个节点只有两个分支,扇出(fan-out)非常小。在存储大量数据时,树的高度会很高,导致查询需要进行大量的磁盘I/O(每次I/O读取一个节点),性能很差。

结论 : 二叉搜索树不适合用作数据库索引,因为它无法保证平衡性,且扇出太小,I/O效率低下。

红黑树 (Red-Black Tree)

定义 : 红黑树是一种自平衡的二叉搜索树。它通过在二叉树每个节点上增加一个存储位来表示节点的颜色(红色或黑色),并通过一组严格的规则来确保树在插入和删除操作后仍然保持"大致平衡",从而保证基本操作的时间复杂度稳定在 O(log n)。

红黑树的五大性质

  1. 每个节点是红色或黑色。
  2. 根节点是黑色。
  3. NIL(空)节点是黑色。
  4. 如果一个节点是红色的,则它的两个子节点都是黑色的。(即,不能有两个连续的红色节点)
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

优点

  • 自平衡:通过旋转和变色操作,在插入和删除后自动调整树的结构,防止树变得过于倾斜,保证了 O(log n) 的操作时间复杂度。
  • 效率高 :对于内存中的数据结构(如Java的 TreeMap, TreeSet),红黑树是非常高效的。

缺点

  • 仍然是二叉树:虽然自平衡,但每个节点最多只有两个子节点,扇出依然很小。
  • 树的高度相对较高:相比于B树/B+树这种多路平衡树,在存储相同数量的数据时,红黑树的高度会更高。
  • 不适合磁盘存储:由于扇出小、树高,进行数据库查询时需要访问的节点数量多,导致磁盘I/O次数多,性能不佳。

结论 : 红黑树是一种优秀的内存数据结构 ,广泛应用于各种编程语言的库中。但由于其扇出小、I/O效率低不适合直接用作数据库(如MySQL)的索引结构。数据库索引需要的是能最大化利用磁盘块、减少I/O次数的结构,这就是为什么选择了B+树而不是红黑树。

总结对比

特性 二叉搜索树 (BST) 红黑树 (Red-Black Tree) B+树 (B+ Tree)
平衡性 不保证,可能退化 自平衡,保证 O(log n) 自平衡,保证 O(log n)
扇出 2(很低) 2(很低) 非常高(可容纳大量子节点)
树高 可能很高(退化时为n) 较高 很低(扇出大)
磁盘I/O 效率极低 效率较低 效率高(核心优势)
范围查询 效率一般(需中序遍历) 效率一般 非常高效(叶子节点链表)
适用场景 小数据量,内存操作 内存中的有序集合(如Java集合) 数据库索引、文件系统

关键点 :数据库(如MySQL)选择B+树而不是二叉树或红黑树,核心原因是优化磁盘I/O性能。B+树通过高扇出降低了树高,减少了查询所需的磁盘访问次数,并通过叶子节点链表极大提升了范围查询的效率。

相关推荐
IT_陈寒22 分钟前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro1 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax2 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH2 小时前
Koa和Express的区别
后端
MariaH2 小时前
Koa框架的使用
后端
luckdewei3 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某4 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy4 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom4 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github
用户1474853079749 小时前
CodeX使用Skill生成游戏美术和音乐资源,一分钟入门
后端