数据库的索引实现--B+Tree

     一上来就B+ Tree可能我也会一脸懵逼,那么植树节刚过,刚好来复习一下各种数吧~

一、二叉查找树

二叉查找树也称为二叉排序树,满足二叉查找树的一般性质,是指一棵空树具有如下性质:

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

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

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

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

二叉查找树,按照中序遍历的方式可以从小到大的顺序排序输出:1,3,4,6,7,8,10,13,14.

进行查找时,从根节点出发,比根节点小则查找左子树,比根节点大则查找右子树。

局限性:一个二叉查找树是由n个节点随机构成,所以,对于某些情况,二叉查找树会退化成一个有n个节点的线性链。

 

二、AVL树

AVL树是带有平衡条件的二叉查找树,左右子树树高不超过1。和红黑树相比,它是严格的平衡二叉树。

不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况。 

局限性:由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。

 

三、红黑树

      一种弱平衡二叉查找树,通过对任何一条从根到叶子的路径上各个节点着色(可以是red或black)的方式的限制,确保没有一条路径会比其它路径长出两倍。

      相对于要求严格的AVL树来说,它的旋转次数变少,所以对于搜索、插入、删除操作多的情况下,我们就用红黑树。

性质:1、每个节点非红即黑; 
2、根节点是黑的; 
3、每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的; 
4、如果一个节点是红的,那么它的两儿子都是黑的; 
5、对于任意节点而言,其到叶子点树NULL指针的每条路径都包含相同数目的黑节点; 
6、每条路径都包含相同的黑节点;

 

Java中TreeMap的实现也是基于红黑树的。

 

四、B-树

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

      B/B+树是为了磁盘或其它存储设备而设计的一种平衡多路查找树。

       在MySQL中的数据一般是放在磁盘中的,读取数据的时候肯定会有访问磁盘的操作。当大规模数据存储到磁盘中的时候,显然定位是一个非常花费时间的过程,但是我们可以通过B树进行优化,提高磁盘读取时定位的效率。

       为什么B类树可以进行优化呢?因为相对于二叉,B树每个内节点有多个分支,可以存储更多索引;与红黑树相比,在相同的的节点的情况下,一颗B/B+树的高度远远小于红黑树的高度。因此磁盘I/O所花的时间也较少。

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、所有叶子结点位于同一层; 
79484711uploading.4e448015.gif转存失败重新上传取消
这里只是一个简单的B树,在实际中B树节点中关键字很多的,上面的图中比如根结点,其中17比表示一个磁盘文件的文件名;小红方块表示这个17文件内容在硬盘中的存储位置;p1表示指向17左子树的指针。

五、B+树

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)才是真正的数据或指向真实数据的指针。

采用左闭合区间原因:

  1. 是因为它要把所有的数据保存在叶子节点。
  2. 因为在mysql中它会认为你的默认的索引,不指定主键索引的话它采用的自增数据结构或者自增的一种机制,它会认为它的最长变的是右边,左边是不长变的。

 

先通过辅助索引索引到主键,再通过主键索引来查询的。

 

那为什么B+树比B树更适合数据库索引?

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

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

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

       其实B树在提高了IO性能的同时并没有解决元素遍历的效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值