动态索引-【B树】

谈到索引原理,无疑就谈到了B树,B+树,那么我们从他们的定义,由来再到细节一一进行了解。

B树:

B树由来:

BST大家都了解是二叉搜索树的意思,但是二叉树他并非都是平衡的,严重失衡的情况下还有可能演化成线性表,从而降低了检索效率。要知道添加索引的主要原因是为了查询速度快,所以其平衡性是非常重要的。
如何保证多分树告诉上的平衡性,不让他退换成线性呢?这就是其B树的诞生缘由。在1970年的时候,R.Bayer和E.Mccreight提出了一种B树。

定义一个m阶的B树满足的条件:

  • 每个结点必须有m个子结点;
  • 除根结点和叶结点之外,其他每个结点必须有m/2(向上取整)个子结点;
  • 根结点至少有两个子结点(特殊情况:根可以为空,或者独根);
  • 所有的叶结点在同一层,关键码范围m/2-1~m-1个 (m/2向上取整);
  • 有k个子结点的结点(分支结点)恰好包含k-1个关键码;

    **对m阶的解释:**m阶标识m路查找,m=2也就是二叉B树。

B树查找:

设B树的高度为3,也就是一个3阶B树,那么在自顶向下检索到叶结点的过程中可能需要进行3次读索引盘(最多3次),再加上根据关键码中隐含指针找到该记录主文件的位置读数据盘1次,所以最多需要N+1次访问外存。
举例:
3阶B树
比如检索关键码31,访问外存的次数为:3次访问索引树节点(a,c,i),1次读取31所在的数据盘位置a12,相加为4次;
又比如检索48,访问外存的次数为:2次访问索引树节点(a,d),1次读取48所在的数据盘位置a6,相加为3次;
这就是B树的查找。

B树的插入:

简单插入,无分裂过程:
插入1
在如上图中,分别加入了14和55,因为是三阶B树,所以每个结点最多包含m-1个关键码,也就是每个结点最多包含2个关键码。
当插入14的时候,需要3次读盘操作(a,b,f),1次写操作,因为f目前只有一个关键码,所以14直接插入到f里即可。
当插入55的时候,需要3次读盘操作(a,d,k),因为将55插入k,导致了k溢出,所以把中间值上移到d位置,分类结点k为k,k’,如上图,因为d结点只有一个关键码48,所以52上移直接插入即可。
复杂插入,因插入元素导致分裂,有可能导致父结点向上溢出:
若插入关键码19的话,我们就上图分析一下:首先经过3次读盘(a,c,g),当在结点g中插入关键码19,导致结点g溢出,分裂出g’,关键码20上移到结点c,导致结点c溢出,分裂出结点c’,中间值关键码23上移到结点a,导致结点a溢出,分裂出结点a’,关键码23上移,生出一个新结点,比如叫t.最后的B树如下图:
插入2
总共写盘次数计算:g,g’,c,c’,a,c’,t一共7次写盘。

B树的删除:

删除需要注意的几个关键:
1. 删除关键码,若该关键码未在叶子结点上,必须交换位置,使其挪动到叶子结点上才能进行删除操作;
2. 根据m阶,要注意每个结点含有的关键码范围为m/2向上取整-1 ~ m-1; 比如5阶,关键码范围为:2~4;
3. 若删除之后,关键码小于最小关键码范围,则考虑向左兄弟借关键码,若左兄弟也很可怜,没有可借给你的,则此时可以考虑和左兄弟结点以及父结点合并;
4. 若m值小,意味着关键码个数少,若删除则出现空结点的范围比较大,所以这种情况,可以先考虑合并,再考虑借关键码;
5. 实际应用中,B树的阶都很大,所以还是考虑借再考虑合并的情况比较多;
以5阶B树为例讲述删除操作(m=5):
5阶B数
因为定义的是5阶B数,所以每个结点含的关键码范围为:2~4;最小为2,最大为4;
删除关键码120,与后继结点交换,也就是120和134交换位置;120删除,结点h含有关键码剩余146一个,不在关键码范围内,所以向左邻居借值,兄弟和父结点一起排序(108,110,115,118,134,146)取中位数(第二位,使得左结点比右结点多一个,不能太贪)作为新分界,也就是118成了新分界,结点h中此刻包含关键码134,146;结点c中包含的关键码未118,150;结点g包含关键码108,110,115;如下图:

删除120之后的B树
此刻再删除120的基础上,我们再删除关键码150,150要和后继156交换位置,i此时只有关键码177,向左邻居借,无可借,进行合并操作,h和156和i合并成i,释放空间结点h;此时父节点c只有118一个关键码,所以也出现了下溢出操作,由于左邻居b无关键码可借,所以合并b,父节点103和c,最后的B树为:
删除150之后的B树

以上就是我们对B树的增,删,查的相关操作和整理。对于B树有如下性质:

性质:

  • B树总是树高平衡的,所有的叶结点都在同一层;
  • 更新和检索操作只影响一些磁盘快,因此性能很好;
  • B树把关键码相近的记录放到同一个磁盘块里,利用了访问局部性原理;
  • B树保证树中至少有一定比例的结点是满的,这样既能够保证一定的空间利用率,又使得插入和删除不必频繁的修改结点,从而整体上减少了磁盘读取数。

下篇整理B+树。

posted on 2018-08-10 20:42  huohuoL  阅读(164)  评论(0编辑  收藏  举报

导航