一 B-Tree
1. d为大于1的一个正整数,称为B-Tree的度。(即一个节点内包含的关键字个数,如图是15 56 77 三个)
2. h为一个正整数,称为B-Tree的高度。(与树的定义相同)
3 .M是节点的孩子个数,称为b树的阶
特性
- B树中每个节点包含了键值和数据对象,
- 任何一个关键字出现且只出现在一个结点中;(15 56 77 等就是关键字)
- 搜索有可能在非叶子结点结束;
- 每个节点的指针上限为2d+1。
二 B+Tree
d h M 的定义与B-Tree一样。
特性:
- 内节点不保存数据,只保留关键字(key),只有叶子节点才保留数据。
- 关键字一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡。
- 搜索一定在叶子节点结束。
- 每个节点的指针上限为2d。
- B+树上增加了顺序访问指针,也就是每个叶子节点增加一个指向相邻叶子节点的指针.
三 B树做文件索引的原因
在对硬盘进行 I/O 操作时,往往需要对可能用到的数据进行预读(提前读取),预读的长度一般为页(page)的整倍数。页是一种存储单位。
根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系 统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B- Tree还需要使用如下技巧:
每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。
综上所述,用B-Tree作为索引结构效率是非常高的。
而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
上文还说过,B+Tree更适合外存索引,原因和内节点出度d有关。从上面分析可以看到,d越大索引的性能越好,而出度的上限取决于节点内key和data的大小:
四 B+Tree 与 B-Tree的对比
- b+树的内节点不保存数据,所以磁盘页能容纳更多关键字,更“矮胖”;
- b+树查询必须查找到叶子节点,b树只要匹配到即可不用管元素位置,因此b+树查找更稳定(并不慢);
- 因为b树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除操作复杂度明显增加。b+树相比来说是一种较好的折中。
- 由于b+树有顺序访问指针,对select 多条查询,只要在一个叶子节点中就能完成。所有叶子节点形成有序链表,便于范围查询。
五 树的查找
B树的简单查找
1. 查找75
先对常驻内存的根节点进行一次顺序查找,正确命中75。
2.查找69
先对常驻内存的根节点进行一次顺序查找,这次查找以失败终止于介乎53和75之间的这个引用。对63和69所在的这个节点进行一次顺序查找,成功找到69。
3.查找45
先对常驻内存的根节点进行一次顺序查找,这次查找以失败终止于53左侧的引用。将19和36这个节点通过IO载入内存,并做一次顺序查找,这次查找以失败终止于36右侧的引用,......最终查找失败于41与49之间的引用。
范围查找(3-11)
自顶向下,查找到范围的下限(3)–>中序遍历到元素6–>中序遍历到元素8–>中序遍历到元素9–>中序遍历到元素11,遍历结束
B+树
查找元素3
范围查找
自顶向下,查找到范围的下限(3)–>通过链表指针,遍历到元素6, 8–>通过链表指针,遍历到元素9, 11,遍历结束
六 B树的设计原因
1.为什么多个孩子节点:降低树的高度,减少磁盘 I/O操作的次数。
2.可以设计成无限多个孩子个数吗?不行,内存好像换不下。
引用:
(强烈推荐)