文件系统索引的数据结构——B-/+Tree

在使用文件时,操作系统需要通过文件名查找到文件的实际地址。建立索引数据结构可以有效加快这个查找过程。目前的文件系统及数据库系统普遍采用B-/+Tree作为索引结构。对于索引查找行为本身来说,如果全部数据都加载进了速度很快的内存,使用传统的二叉树作为索引也未尝不可。但因为索引数据太大,一般不能全部加载到内存。相对于内存存取,I/O存取的消耗要高几个数量级,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

 

磁盘往往不是严格按需读取,而是每次都会预读。即读取完需要的数据,会顺序向后读一定长度的数据放入内存。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性(使用的数据位置较为集中)的程序来说,预读可以提高I/O效率。预读的长度一般为页大小的整倍数。对于文件系统索引中的树实现,每次新建节点会直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个结点只需一次I/O。在此基础上,只需要减少节点遍历次数——即控制树的高度,就可以有效减少I/O次数。

从这个条件可以知道,二叉树并不合适,因为二叉树无法控制高度。红黑树也具有同样的问题,而且逻辑上很近的节点(父子)物理上可能很远,无法利用局部性。而在B-/+Tree中,每个节点对应很多子节点,插入节点时增加子节点而不是增加树高度。这样对于减少I/O次数目标的达成更为有利。

 

在这里我们还可以对B树和B+树的性能进行对比。B+树的内部结点并没有指向关键字具体信息的指针(比如文件内容的具体地址)。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。这样,一次性读入内存中的需要查找的关键字也就越多。相对来说I/O次数也就更低了。

另外,也有说法认为B+树的查询效率更加稳定是其相对于B树的优势。因为B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。

在范围查询(range-query)方面,B+树的优势更加明显。B树的范围查找需要不断依赖中序遍历。首先二分查找到范围下限,在不断通过中序遍历,知道查找到范围的上限。整个过程比较耗时。而B+树的范围查找则简单了许多。首先通过二分查找,找到范围下限,然后同过叶子结点的链表顺序遍历,就可以找到上限,整个过程简单许多,效率也比较高。但range-query在数据库中应用比较频繁,在传统文件系统中可能意义不是很大。

猜你喜欢

转载自blog.csdn.net/FYZDMMCpp/article/details/90815867
今日推荐