参考:https://blog.csdn.net/qq_25940921/article/details/82224418
B树每次都从根节点开始查找值,B树每个节点有key和value,查找时,可能不需要
那么多value占用很多空间。
所以,B+树在B树的基础上做了优化,它与B树的差异在于:
(1)有 k 个子节点的节点必然有 k 个key;
(2)非叶子节点仅具有索引作用,跟记录有关的信息均存放在叶子节点中。
(3)树的所有叶子节点构成一个有序链表,可以按照key排序的次序遍历全部记录。

即,B和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。
B+树的优点在于:
1.由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。
数据存放的更加紧密,具有更好的空间局部性。
因此访问叶子节点上关联的数据也具有更好的缓存命中率。
2.B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。
而且由于数据顺序排列并且相连,所以便于区间查找和搜索。
而B树则需要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。
但是B树也有优点,其优点在于:
由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。
B树
一颗m阶的B树(B-tree) 定义如下:
(1)每个节点最多有 m-1 个key;
(2)根节点至少有1个key;
(3)非根节点至少有 Math.ceil(m/2)-1 个key;
(4)每个节点中的key都按照从小到大的顺序排列,每个key的左子树中的所有key都小于它,而右子树中的所有key都大于它;
(5)所有叶子节点都位于同一层,即根节点到每个叶子节点的长度都相同。
如下图是一棵4阶B树(2-3-4树),

而对于B树节点的插入,可以类比2-3-4树,即,若节点插入节点的key还未“丰满”,则直接插入,若节点插入节点的key已“丰满”,则插入节点之后分裂,再以分裂之后的父节点看作向上层插入的节点调整,直至满足该 m 阶的B树
B+树
虽然B树这种数据结构,应用在内外存交互,可以极大的减少磁盘的IO次数,但还是有些小瑕疵,如下5阶的B树图,若我需要读取key为“66”与“73”的数据,则此时从根节点“50”开始,“66”大于“50”,找右孩子,即到“60 70 120”的节点,再锁定到“64 66”的节点,找到key为“66”的数据,然后读“73”的数据,再重新从根开始往下寻找key为“73”的数据,如果需要查询的数据量一多,性能就很糟糕。还有一点,就是B树的每个节点都包含key及其value数据,这样的话,我每次读取叶子节点的数据时,在经过路径上的非叶子节点也会被读出,但实际上这部分数据我是不需要的,这样又占用了没有必要的内存空间。
2646

被折叠的 条评论
为什么被折叠?



