Mysql中的B树和B+树

在这里插入图片描述B树是一颗平衡的多叉检索树,它具有以下性质:

所谓检索树是指这样的树:树中任意非叶子节点A作为根节点的子树,其左子树上节点中的元素值均小于或等于节点A中元素的值;其右子树上节点中的元素值均大于或等于节点A中元素的值。
检索树又称为排序树、有序树,如果将检索树降维成表结构则同样可以使用二分查找法进行节点检索,且时间复杂度基本不变。

如果不加任何构造限制,那么在树结构中检索元素的时间复杂度可能为O(n)。
这显然失去了检索树的意义,如果一颗检索树能够保证树的高度H限制在节点数N的对数阶范围内(H=O(logn)),这样的检索树就称为平衡树。在编程实践中只要保证树中任意两个子树深度差的绝对值不大于1,就可以保证前述条件成立。另外B树中对深度差绝对值做了更严格的规定,即所有叶子结点都位于同一深度。

一颗B树的非叶子节点能够最多关联的子节点数量称为阶数。B树中的阶数至少为3,因为当阶数为2时B树进行节点分裂就可能会出现某叶子节点没有任何元素的情况。

树中每个非根节点所包含的元素个数 j 满足:(N/2) - 1 <= j <= N - 1,其中N表示B树的阶数。例如阶数为3的B树每一个非叶子结点能够存储的元素个数可能为 0个、1个和2个(但0个元素没有任何检索意义,还会造成树中任意两个子树深度差的绝对值改变)。

树中一个节点可关联的子节点数量比以上文字中提到的元素最大个数多1。也就是说阶数为3的B树每个节点最多可关联3个子节点。

在这里插入图片描述上图展示了一颗3阶B树,它的每个节点最多可以有3个子节点,并且每个子节点中最多有2个元素。可以观察到B树满足检索树的基本规则:凡是比给定元素值大的所有元素,都作为该元素的子元素排列在该元素的左子树上;凡是比给定元素值大的所有元素,都作为该元素的子元素排列在该元素的右子树上。这样一来开发人员就可以使用和二分查找法类似的查找方式定位要查询的元素,或者在插入一个新元素前定位到新元素将要进行插入的位置。

下图演示了在B树中依次添加元素时的分裂和节点间关联过程,这些元素的值依次增大分别是:3、5、7、9、14、13、15、16、18、22、25、31、33。在实际应用开发中,虽然我们并不能保证插入B树的元素值都是增加的,但是对B树的插入操作过程却是相同的(两者的区别只是定位的将要插入新元素的位置不一样)
在这里插入图片描述
变体B+树
B树的优点很明显:无论进行新元素的插入定位还是进行指定元素的查找,都可以快速完成这些定位/查找动作,其查询性能的时间复杂度相当于二分查找法**(O(log(n)))**。但是B树的缺点也很明显首先插入新元素时可能涉及到树深度的改变,当然这个问题可以通过增加B树的阶数来解决。也就是让每一个节点可以拥有更多的子节点,这样就可以在存储元素总量不变的情况下减少树的理论深度,从而减少发生树深度改变的情况,

另一个问题就稍微严重一些了,那就是B树并不适合管理InnoDB引擎中的数据(这个在后文会进行说明)。还好B树结构有一个变体结构,称为B+树。两者最大的区别是,后者在B树的结构基础上扩展出了一个链表存储结构,并且在树的叶子节点对非叶子结点元素进行了冗余存储。如下图所示:
在这里插入图片描述· B树和B+树在新元素插入、元素删除、元素查找等基本处理方式上没有太大的区别。但是B+树的两个典型的结构变动刚好可以改进树结构在InnoDB引擎中的应用:
由于B+树的叶子节点存储了非叶子节点的冗余元素,所以我们可以在
非叶子节点只记录某条数据的索引信息
而在叶子节点记录具体的数据信息。那么MySQL数据库就可以在InnoDB引擎启动时就加载B+树的非叶子节点到内存特定区域,这样做的最大好处是可以在内存空间和查找速度两个维度上找到最好的平衡点

特别注意的是,实际在InnoDB引擎中的B+树结构,其叶子节点并不是存储一行数据(要真是这样,这颗B+树不知道需要有多大。。。),而是和Data Page作为对应。在之前介绍InnoDB引擎的文章中已经说明过数据库中Page的概念。Page是InnoDB引擎中最基本的数据操作单元,无论是InnoDB从磁盘上读取数据还是改变数据,都以Page作为操作单位。同样,InnoDB引擎中的索引结构也以Page为单位在叶子节点关联具体数据。
另外B+树在最底层将所有叶子节点串成了一个链表结构(不用担心某个叶子节点没有任何元素,因为B+树遵循所有B树的基本约束),这样一来在进行数据查找时就可以使用表结构进行元素的依次查找,而无需再进行树的遍历操作。实际上在InnoDB引擎中每一个叶子节点都是一个Page信息,构成链表结构后就可以检索每一个Page的上一个Page和下一个Page信息,这恰好也是InnoDB引擎中预读功能的实现基础

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值