面试官:为什么InnoDB用的是B+Tree

407 阅读3分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

前言

面试造火箭,工作拧螺丝,这里是造火箭系列第四期,今天我们来造的火箭主题是 —— B+ Tree,同样的,这个问题也是经典的面试猛如虎,工作没卵用系列,虽然我们工作的时候并不需要去了解那么多这些相关的问题,但是怎奈何面试的时候要用啊,所有,我们也来聊聊这个问题。

需求分析

我们知道对于索引来说,最重要的就是优化查询的过程,而对于查找来说,主要可以分为精确查找和范围查找两个类别,但其实,如果对于一个有序的数组来说,直接进行二分查找就非常的快了,并不需要去使用索引。

但是却会有一个问题,那就是在插入数据的时候,性能会非常的差,因为要保证数组的有序,所以时间复杂度要去到O(n)级别。

还有一个问题,那就是如果数组的大小超过了内存的大小,那么就需要考虑怎么把一部分数据被放到磁盘中,同时对于一个有序数组的增删改的性能都是非常的差的。

二分搜索树

通过上面的问题,能想到的第一个版解决方案,那就是使用二分搜索树来替代所用的有序数组,通过这样的替换,原来增删改的O(n)的复杂度就变成了O(logn),同时查询的时候的复杂度也变成了O(logn)。

image.png

弊端

但是二分搜索树同样存在一个弊端,那就是在进行范围查询的时候非常的麻烦,因为他需要不断的从根节点开始向下遍历,所以会很慢。

解决方案

为了解决这个问题,我们对树的结构进行第二次的改造,把所有的数据都存在于根节点处,然后根节点之间通过指针相连,也就是对于树的根节点,相当于是一个双向链表。

这样的方式就解决了范围查询的一个问题,在范围查询或者是精确查询的时候,效率都还过得去。

image.png

多叉树

对于二分搜索树来说,其查询的效率是跟树的高度有关的,假设我们有2000万的数据规模,那么就大概需要有25BST的一个树高的树才可以装下整个数据,那么在查询的时候,需要进行25次的I/O操作。

我们对它进一步的优化步骤,就是把树变得更加的矮胖,也就是把二分搜索树,变成一个多叉搜索树

image.png

这个多叉搜索树,其实也就是B+Tree,它的一个主要特点就是,所有数据只存在于叶子节点,同时叶子节点之间通过双端链表连接起来,从而优化了范围查询的问题。

B-Tree和B+Tree的区别

B-Tree相对于B+Tree来说,最大的区别就是他的数据是存在于每一个节点的,并不像B+Tree那样都是存在于叶子节点。

而对于这两种树的主要区别就是在进行范围查询的时候,因为B-Tree节点间是通过父子关系连接的,所以如果使用范围查询的时候,就必须通过回表的方式来查询。

而B+Tree因为有了双向链表的关系,所以不会有这个问题。

最后

面试造火箭系列这期就到这里,让我们下期再见。