B树
B树又名平衡多路查找树,即一个结点的查找路径不止左、右两个,而是有多个。数据库索引技术里大量使用者B树和B+树的数据结构。一个结点存储多个值(索引)。
B树的阶数:M阶表示一个B树的结最多有多少个查找路径(即这个结点有多少个子节点)。M=2是二叉树,M=3则是三叉树。
一棵M阶B树有以下特点。
特点:
- 每个结点的值(索引) 都是按递增次序排列存放的,并遵循左小右大原则。
- 根结点的子节点个数为 [2,M]。
- 除根结点以外的非叶子结点的子节点个数为[Math.ceil(M/2),M],Math.ceil() 为向上取整。
- 每个非叶子结点的值(索引) 个数 = 子节点个数 -1 。最小为 Math.ceil(M/2)-1 最大为 M-1 个。
- B树的所有叶子结点都位于同一层。
下图是一个3阶B树:
B树优点
- B树的一个结点可以装多个值,读取时,是把整个结点读到内存,然后在内存中,对结点的值进行处理,在内存中处理速度肯定比磁盘快。树有多少层,就意味着要读多少次磁盘IO。所以树的高度越矮,就意味着查询数据时,需要读IO的次数就越少(众所周知,读IO是一件费事的操作)。
- B树的每一个结点都包含key(索引值) 和 value(对应数据),因此方位离根结点近的元素会更快速。(相对于B+树)
B树的不足
- 不利于范围查找(区间查找),如果要找 0~100的索引值,那么B树需要多次从根结点开始逐个查找。
B+树
B+树是基于B树的基础提出的,它与B树的差异在于:
- 非叶结点仅具有索引作用,数据均存放在叶结点中。
- 树的所有叶结点构成一个双向链表,可以按照关键码排序的次序遍历全部记录。
下图是一棵3阶B+树:
B+树的优点
- 由于B+树在内部节点上不好含数据信息,因此在内存页中能够存放更多的key。数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的数据也具有更好的缓存命中率。
- B+树的叶子结点通过双向链表相连,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。