百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> 为何MySQL数据库索引选中运用B+树?
分享文章到:

为何MySQL数据库索引选中运用B+树?

发布时间:05/13 来源:未知 浏览: 关键词:

在进一步剖析为何MySQL数据库索引选中运用B+树以前,我信赖许多小同伴对数据构造中的树还是有些许依稀的,因而我们由浅入深一步步探究树的演进历程,在一步步引出B树以及为何MySQL数据库索引选中运用B+树!

学过数据构造的个别对最根基的树都有所相识,因而我们就从与我们主题更为附近的二叉查找树开端。

一、二叉查找树

(1)二叉树简介:

二叉查找树也称为有序二叉查找树,知足二叉查找树的个别性质,是指一棵空树拥有如下性质:

1、任意节点左子树不为空,则左子树的值均小于根节点的值;

2、任意节点右子树不为空,则右子树的值均大于于根节点的值;

3、任意节点的左右子树也离别是二叉查找树;

4、没有键值相称的节点;


上图为一个普通的二叉查找树,按照中序遍历的方式可以从小到大的次序排序输出:2、3、5、6、7、8。

对上述二叉树进行查找,如查键值为5的记载,先找到根,其键值是6,6大于5,因而查找6的左子树,找到3;而5大于3,再找其右子树;一共找了3次。要是按2、3、5、6、7、8的次序来找一样需求3次。用一样的要领在查找键值为8的这个记载,这次用了3次查找,而次序查找需要6次。盘算均匀查找次数得:次序查找的均匀查找次数为(1+2+3+4+5+6)/ 6 = 3.3次,二叉查找树的均匀查找次数为(3+3+3+2+2+1)/6=2.3次。二叉查找树的均匀查找速度比次序查找来得更快。

(2)局限性及利用

一个二叉查找树是由n个节点随机形成,所以,关于某些状况,二叉查找树会退化成一个有n个节点的线性链。如下图:


大家看上图,要是我们的根节点选中是最小或者最大的数,那么二叉查找树就完全退化成了线性构造。上图中的均匀查找次数为(1+2+3+4+5+5)/6=3.16次,和次序查找差不多。显然这个二叉树的查询效率就很低,因而若想最大机能的结构一个二叉查找树,需要这个二叉树是均衡的(这里的均衡从一个显著的特色可以看出这一棵树的高度比上一个输的高度要大,在雷同节点的状况下也就是不均衡),从而引出了一个新的定义-均衡二叉树AVL。

二、AVL树

(1)简介

AVL树是带有均衡前提的二叉查找树,个别是用均衡因子差值判断是否均衡并通过扭转来实现均衡,左右子树树高不超过1,和红黑树比拟,它是严厉的均衡二叉树,均衡前提必须知足(所有节点的左右子树高度差不超过1)。无论我们是施行插入还是删除操纵,只有不知足上面的前提,就要通过扭转来维持均衡,而扭转是非常耗时的,由此我们可以晓得AVL树适合用于插入删除次数比较少,但查找多的状况。

从上面是一个普通的均衡二叉树,这张图我们可以看出,任意节点的左右子树的均衡因子差值都不会大于1。

(2)局限性

因为保护这种高度均衡所付出的代价比从中获得的效率收益还大,故而现实的利用不多,更多的地方是用寻求部分而不是非常严厉整体均衡的红黑树。当然,要是利用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。

(3)利用

1、Windows NT内核中宽泛存在;

三、红黑树

(1)简介

一种二叉查找树,但在每个节点添加一个存储位表示节点的色彩,可以是red或black。通过对任何一条从根到叶子的途径上各个节点着色的方式的限定,红黑树确保没有一条途径会比其它途径长出两倍。它是一种弱均衡二叉树(因为是若均衡,可以推出,雷同的节点状况下,AVL树的高度低于红黑树),相关于要求严厉的AVL树来说,它的扭转次数变少,所以关于搜寻、插入、删除操纵多的状况下,我们就用红黑树。

(2)性质

1、每个节点非红即黑;

 2、根节点是黑的;

3、每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的;

4、要是一个节点是红的,那么它的两儿子都是黑的;

5、关于任意节点而言,其到叶子点树NULL指针的每条途径都包含雷同数量的黑节点;

6、每条途径都包含雷同的黑节点;

(3)利用

1、宽泛用于C++的STL中,Map和Set都是用红黑树实现的;

2、闻名的Linux进程调度Completely Fair Scheduler,用红黑树治理进程控制块,进程的虚拟内存区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间;

3、IO多路复用epoll的实现采纳红黑树组织治理sockfd,以支撑迅速的增删改查;

4、Nginx中用红黑树治理timer,由于红黑树是有序的,可以很快的得到距离目前最小的定时器;

5、Java中TreeMap的实现;

四、B/B+树

说了上述的三种树:二叉查找树、AVL和红黑树,似乎我们尚无摸到MySQL为何要运用B+树作为索引的实现,不要急,接下来我们就先探究一下什么是B树。

(1)简介

我们在MySQL中的数据个别是放在磁盘中的,读取数据的时候确定会有访问磁盘的操纵,磁盘中有两个机械运动的局部,离别是盘片扭转和磁臂移动。盘片扭转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片扭转到指定位置今后,移动磁臂后开端进行数据的读写。那么这就存在一个定位到磁盘中的块的历程,而定位是磁盘的存取中破费工夫比较大的一块,究竟机械运动破费的时候要远弘远于电子运动的工夫。当大规模数据存储到磁盘中的时候,显然定位是一个非常破费工夫的历程,但是我们可以通过B树进行优化,提高磁盘读取时定位的效率。

为何B类树可以进行优化呢?我们可以依据B类树的特色,结构一个多阶的B类树,然后在尽量多的在结点上存储相干的信息,保证层数尽量的少,以便背面我们可以更快的找到信息,磁盘的I/O操纵也少一些,而且B类树是均衡树,每个结点到叶子结点的高度都是雷同,这也保证了每个查询是不乱的。

总的来说,B/B+树是为了磁盘或其它存储设施而设计的一种均衡多路查找树(相关于二叉,B树每个内节点有多个分支),与红黑树比拟,在雷同的的节点的状况下,一颗B/B+树的高度远远小于红黑树的高度(在下面B/B+树的机能剖析中会提到)。B/B+树上操纵的工夫平常由存取磁盘的工夫和CPU盘算工夫这两局部形成,而CPU的速度非常快,所以B树的操纵效率取决于访问磁盘的次数,要害字总数雷同的状况下B树的高度越小,磁盘I/O所花的工夫越少。

注意B-树就是B树,-只是一个符号。

(2)B树的性质

1、定义任意非叶子结点最多只要M个儿子,且M>2;

2、根结点的儿子数为[2, M];

3、除根结点之外的非叶子结点的儿子数为[M/2, M];

4、每个结点寄存至少M/2-1(取上整)和至多M-1个要害字;(至少2个要害字)

5、非叶子结点的要害字个数=指向儿子的指针个数-1;

6、非叶子结点的要害字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7、非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向要害字小于K[1]的子树,P[M]指向要害字大于K[M-1]的子树,其它P[i]指向要害字属于(K[i-1], K[i])的子树;

8、所有叶子结点位于统一层;


这里只是一个简略的B树,在现实中B树节点中要害字许多的,上面的图中比方35节点,35代表一个key(索引),而小黑块代表的是这个key所指向的内容在内存中现实的存储位置,是一个指针。

五、B+树

(1)简介

B+树是应文件系统所需而发生的一种B树的变形树(文件的目录一级一级索引,只要最底层的叶子节点(文件)保留数据)非叶子节点只保留索引,不保留现实的数据,数据都保留在叶子节点中,这不就是文件系统文件的查找吗?

我们就举个文件查找的例子:有3个文件夹a、b、c, a包含b,b包含c,一个文件yang.c,a、b、c就是索引(存储在非叶子节点), a、b、c只是要找到的yang.c的key,而现实的数据yang.c存储在叶子节点上。

所有的非叶子节点都可以看成索引局部!

(2)B+树的性质(下面提到的都是和B树不雷同的性质)

1、非叶子节点的子树指针与要害字个数雷同;

2、非叶子节点的子树指针p[i],指向要害字值属于[k[i],k[i+1]]的子树.(B树是开区间,也就是说B树不允许要害字反复,B+树允许反复);

3、为所有叶子节点添加一个链指针;

4、所有要害字都在叶子节点涌现(稠密索引). (且链表中的要害字刚好是有序的);

5、非叶子节点相当于是叶子节点的索引(希罕索引),叶子节点相当于是存储(要害字)数据的数据层;

6、更适合于文件系统;

非叶子节点(比方5,28,65)只是一个key(索引),现实的数据存在叶子节点上(5,8,9)才是真正的数据或指向真实数据的指针。

(3)利用  

1、B和B+树主要用在文件系统以及数据库做索引,比方MySQL;

六、B/B+树机能剖析

n个节点的均衡二叉树的高度为H(即logn),而n个节点的B/B+树的高度为logt((n+1)/2)+1;

若要作为内存中的查找表,B树却不一定比均衡二叉树好,尤为当m较大时更是如此。由于查找操纵CPU的工夫在B-树上是O(mlogtn)=O(lgn(m/lgt)),而m/lgt>1;所以m较大时O(mlogtn)比均衡二叉树的操纵工夫大得多。因而在内存中运用B树必须取较小的m。(平常取最小值m=3,此时B-树中每个内部结点可以有2或3个孩子,这种3阶的B-树称为2-3树)。

七、为何说B+树比B树更适合数据库索引?

1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向要害字具体信息的指针,因而其内部节点相对B树更小,要是把所有统一内部节点的要害字寄存在统一盘块中,那么盘块所能容纳的要害字数目也越多,一次性读入内存的需要查找的要害字也就越多,相对IO读写次数就降低了。

2、B+树的查询效率更加不乱:因为非终结点并不是终究指向文件内容的结点,而只是叶子结点中要害字的索引。所以任何要害字的查找必须走一条从根结点到叶子结点的路。所有要害字查询的途径长度雷同,导致每一个数据的查询效率相当。

3、因为B+树的数据都存储在叶子结点中,分支结点均为索引,利便扫库,只需要扫一遍叶子结点即可,但是B树由于其分支结点一样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的状况,所以平常B+树用于数据库索引。

PS:我在知乎上看到有人是这样说的,我感觉说的也挺有原理的:

他们以为数据库索引采纳B+树的主要缘由是:B树在提高了IO机能的同时并没有解决元素遍历的我效率低下的题目,正是为理解决这个题目,B+树利用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范畴的查询是非常频繁的,而B树不支撑这样的操纵或者说效率太低。

总结

以上就是这篇文章的全部内容了,但愿本文的内容对大家的学习或者工作拥有一定的参考学习价值,感谢大家对脚本之家的支撑。要是你想理解更多相干内容请查看下面相干链接

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有159人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板