B+树相关数据结构和算法

二分查找法

二分查找法(binary search)也称为折半查找法,用来查找一组有序的记录数组中的某一记录,简单来讲就是将记录按照有序化(递增递减)排列,在查找过程中采用跳跃式方式查找,即先以有序序列的中间位置为比较对象,如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。一次比较将查找区间缩小一半。具体如下:
在这里插入图片描述

这里有10个数字,现在需要查找48这条记录,二分法查找过程如上,第一次查找为37,48大于37所以在右侧再次二分法查询,这次定位为50大于48在左侧查询,可以得到48,整个过程用3次就查到了。但是如果使用顺序查找的方式需要7次。但是如果要查的数据为5,顺序方式只用1次就可以,二分法需要4次。但实际上二分法查找效率是高于顺序查找的,对于上面的10个数字来说,顺序查找平均查找次数为(1+2+3+4+5+6+7+8+9+10)/10=5.5次。通过二分法进行查找为(4+3+2+4+3+1+4+3+2+3)/10=2.9次。在效率最差的情况,顺序查找需要10次,二分法只需要4次。Innodb存储引擎下二分法应用在每页Page Directory中的槽是按照主键的顺序存放的,对于某一条具体记录的查询是通过对Page Directory进行二分法查找得到的。

二叉查找树和平衡二叉树

B+树是通过二叉查找树,再由平衡二叉树,B树演化而来的。

如图为一棵二叉查找树:
在这里插入图片描述

上图中的每个节点代表每个节点的键值,在二叉查找树中,左子树的键值总是小于根的键值,右子树的键值总是大于根的键值。因此可以通过中序遍历得到键值的排序输出,上图二叉查找树经过中序遍历后输出:2、3、5、6、7、8。对于这棵树的查找,如现在需要查找5这条记录,查找过程如下:先找到根,其键值为6,6>5,因此需要找到6的左子树,找到3。3小于5则找其右子树,一共找了3次。顺序查找的方式也会查询3次。如果查找的记录为8也需要3次,但是顺序查找会查找6次。计算一下平均查找次数可以得到:顺序查找平均查找次数为(1+2+3+4+5+6)/6=3.3次;二叉查找树的平均查找次数为(3+3+3+2+2+1)/6=2.3次,所以二叉查找树比顺序查找更快一些。

二叉查找树可以随意构造,同样的数字还可以构造成如下所示
在这里插入图片描述

这棵树的平均查找次数为(1+2+3+4+5+5)/6=3.16次,和顺序查找差不多,这棵树的效率比上面的效率要低一些,因此要想最大性能的构造一棵二叉查找树,需要这棵二叉查找树是平衡的从而出现了新的定义——平衡二叉树,或称为AVL树。

平衡二叉树的定义如下:

首先需要符合二叉查找树的定义,其次必须满足任何节点的两个子树的高度最大差为1。所以上面的二叉树是不符合这个要求的。平衡二叉树的查找性能是比较高的,但不是最高的,做好的性能需要建立一棵最优二叉树,但是最优二叉树的建立和维护需要大量的维护操作,因此用户往往建立一棵平衡二叉树即可。

平衡二叉树的查询速度确实很快,但是维护一棵平衡二叉树的代价非常大,通常来说需要1次或者多次左旋或者右旋来得到插入或者更新后树的平衡性。如下两种情况。
在这里插入图片描述

除了插入操作,还有更新和删除的操作,不过这和插入没有本质的区别,都是通过左旋或者右旋来完成的,因此维护平衡二叉树是有开销的,但是二叉树多用于内存之中,虽然有一定的开销,但是对数据库而言影响较小。

B+树

B+树是为磁盘或其他直接存取辅助设备设计的一种平衡查找树,在B+树上,所有记录的节点都是按键值的大小顺序存放在同一层的叶子节点上,并且是顺序存放的,如果用户从最左面的叶子节点开始顺序遍历,可以得到所有键值的顺序排序:5、10、15、20、25、30、50、55、60、65、75、80、85、90
在这里插入图片描述

B+树的插入操作

B+树的插入必须保证插入后叶子节点中的记录依然排序,同时需要考虑插入到B+树的三种情况,每种情况都可能会导致不同的插入算法。如下所示:
在这里插入图片描述

第一种情况:Leaf Page与Index Page都没有满直接插入即可

此时需要插入28这个键值
在这里插入图片描述

第二种情况:Leaf Page满了但是Index Page还没有满,拆分操作

此时需要插入70这个键值
在这里插入图片描述

直接插入的Leaf Page情况为50、55、60、65、70,但是因为叶已经满了,所以根据中间值60来拆分叶子节点成下图所示。

第三种情况:Leaf Page与Index Page都被写满了,这个时候需要进行两次拆分

此时插入的值为95这个键值
在这里插入图片描述

不管怎么变化,B+树总是会保持平衡,但是为了保持平衡对于新插入的键值可能需要做大量的拆分页(split)操作,因为B+树的结构主要用于磁盘,页的拆分意味着磁盘的操作,所以应该在可能的情况下尽量减少页的拆分操作。因此B+树同样提供类似于平衡二叉树的旋转(Rotation)功能。旋转发生在Leaf Page已经满,但是其左右兄弟节点没有满的情况下。这时B+树并不会急于去拆分页的操作,而是将记录移动到所在页的兄弟节点上。通常情况下,左兄弟会首先检查用来做旋转操作。

当插入值70的时候,B+树使用旋转的方式就变成下图所示状态,可以减少一次页的拆分操作,同时这棵B+树的高度依然是2
在这里插入图片描述

B+树的删除操作

B+树使用填充因子(fill factor)来控制树的删除变化,50%是填充因子可以设置的最小值。(填充因子就是每个页存放多少键值,例如上图中一个页4个键值,那么一个页在设置50%为最小填充因子那么一个页最少也要有两个键值才可以)。B+树的删除操作同样必须保证删除后叶子节点中的记录依然排序,同插入一样,B+树的删除操作同样需要考虑以下三种情况:
在这里插入图片描述
以下图为例,当需要删除键值为70这条记录,该记录符合第一种情况,直接删除即可
在这里插入图片描述

上图中左侧为未删除之前的状态,现在需要删除70这个键值,该值删除后填充因子仍然满足50%,同时不是Index Page的节点,所以直接删除就可以。

删除键值为25这条记录,该记录符合第一种情况,但是该节点是Index Page中的值因此在删除后,还要吧25的右兄弟节点的28更新到Index Page中。
在这里插入图片描述

删除键值为60的情况,删除Leaf Page中键值为60的记录后,Fill Factor小于50%,这时需要做合并操作,同样在删除Index Page中需要做Index Page合并的操作。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值