B+树索引概述

来源:互联网 发布:八进制转十进制算法 编辑:程序博客网 时间:2024/05/21 09:44

1. B+树索引概述

在上一篇文章中,我们讨论了关于index的几个中重要的课题:

A) index是保存在磁盘上的一种数据结构,用于提高查询或是扫描record的速度。

B) 排序索引树通过保存page的指针加速record的查找。(ISAM

C) 维护排序索引树的代价很高,因此,ISAM通过创建overflow page来解决这个问题,但是过多的overflow page会使查询性能从log(指数log)级别降低到线性遍历。

下面我们将介绍一种高度健壮的、比较流行的一种数据结构——B+树,作为ISAM的扩展。

一般说来,B+树是一种高效的基于磁盘保存的数据结构,主要保存(key, value)pair。它支持对key的高效查找,和高效的范围迭代。

B+树提供了这些功能:

A) 快速的record查找

B) 快速的record遍历

C) 不通过overflow page的形式维护排序树结构

B+树背后的关键思想是利用有序平衡树,替代ISAM中的排序树。

2. B+树的定义

B+树是用磁盘上的page作为node节点的树。B+树中的节点可以区分为leaf node(叶子节点)和interior node(内部节点)。

由于每一个node刚好是磁盘中的一个page,在B+树中,我们使用的术语nodepage是可以互换的。


2. B+树索引的管理机制


    2.1 B+树索引对于插入的管理

 

    对于B树索引的插入情况的描述,可以分为两种情况:

 

    一种是在一个已经充满了数据的表上创建索引时,索引是怎么管理的;

 

    另一种则是当一行接着一行向表里插入或更新或删除数据时,索引是怎么管理的。

 

对于第一种情况来说,比较简单。当在一个充满了数据的表上创建索引(create index命令)时,oracle

 

先扫描表里的数据并对其进行排序,然后生成叶子节点。生成所有的叶子节点以后,根据叶子节点的数量生

 

成若干层级的分支节点,最后生成根节点。这个过程是很清晰的。

 

当一开始在一个空的表上创建索引的时候,该索引没有根节点,只有一个叶子节点。

 

随着数据不断被插入表里,该叶子节点中的索引条目也不断增加,当该叶子节点充满了索引条目而不能再放

 

下新的索引条目时,该索引就必须扩张,必须再获取一个可用的叶子节点。这时,索引就包含了两个叶子节

 

点,但是两个叶子节点不可能单独存在的,这时它们两必须有一个上级的分支节点,其实这也就是根节点

 

了。于是,现在,我们的索引应该具有3个索引块,一个根节点,两个叶子节点。

 

叶子节点的拆分过程。这个过程需要分成两种情况,一种是插入的键值不是最大值;另一种是插入的键值是最大值。

 

对于第一种情况来说,当一个非最大键值要进入索引,但是发现所应进入的索引块不足以容纳当前键值时:

 

1)从索引可用列表上获得一个新的索引数据块。

 

2)将当前充满了的索引中的索引条目分成两部分,一部分是具有较小键值的,另一部分是具有较大键值的。

 

Oracle会将具有较大键值的部分移入新的索引数据块,而较小键值的部分保持不动。

 

3)将当前键值插入合适的索引块中,可能是原来空间不足的索引块,也可能是新的索引块。

 

4)更新原来空间不足的索引块的kdxlenxt信息,使其指向新的索引块。

 

5)更新位于原来空间不足的索引块右边的索引块里的kdxleprv,使其指向新的索引块。

 

6)向原来空间不足的索引块的上一级的分支索引块中添加一个索引条目,该索引条目中保存新的索引块里的最小键值,以及新的索引块的地址。

 

从上面有关叶子节点分裂的过程可以看出,其过程是非常复杂的。因此如果发生的是第二种情况,则为了简

 

化该分裂过程,oracle省略了上面的第二步,而是直接进入第三步,将新的键值插入新的索引块中。

 

 

在上例中,当叶子节点越来越多,导致原来的根节点不足以存放新的索引条目(这些索引条目指向叶子节

 

点)时,则该根节点必须进行分裂。当根节点进行分裂时:

 

1)从索引可用列表上获得两个新的索引数据块。

 

2)将根节点中的索引条目分成两部分,这两部分分别放入两个新的索引块,从而形成两个新的分支节点。

 

3)更新原来的根节点的索引条目,使其分别指向这两个新的索引块。

 

因此,这时的索引层次就变成了2层。同时可以看出,根节点索引块在物理上始终都是同一个索引块。而随着

 

数据量的不断增加,导致分支节点又要进行分裂。分支节点的分裂过程与根节点类似(实际上根节点分裂其

 

实是分支节点分裂的一个特例而已):

 

1)从索引可用列表上获得一个新的索引数据块。

 

2)将当前满了的分支节点里的索引条目分成两部分,较小键值的部分不动,而较大键值的部分移入新的索引块。

3)将新的索引条目插入合适的分支索引块。

 

4)在上层分支索引块中添加一个新的索引条目,使其指向新加的分支索引块。

 

当数据量再次不断增加,导致原来的根节点不足以存放新的索引条目(这些索引条目指向分支节点)时,再

 

次引起根节点的分裂,其分裂过程与前面所说的由于叶子节点的增加而导致的根节点分裂的过程是一样的。

 

 

同时,根节点分裂以后,索引的层级再次递增。由此可以看出,根据B树索引的分裂机制,一个B树索引始终

 

都是平衡的。注意,这里的平衡是指每个叶子节点与根节点的距离都是相同的。同时,从索引的分裂机制可

 

以看出,当插入的键值始终都是增大的时候,索引总是向右扩展;而当插入的键值始终都是减小的时候,索

 

引则总是向左扩展。


0 0
原创粉丝点击