B数据库
B+数组
这两种处理索引的数据结构的不一样之处:数据结构
1. B树中同一键值不会出现屡次,而且它有可能出如今叶结点,也有可能出如今非叶结点中.而B+树的键必定会出如今叶结点中,而且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡.spa
2.由于B树键位置不定,且在整个树结构中只出现一次,虽然能够节省存储空间,但使得在插入、删除操做复杂度明显增长.B+树相比来讲是一种较好的折中.操作系统
3.B树的查询效率与键在树中的位置有关,最大时间复杂度与B+树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候).而B+树的时候复杂度对某建成的树是固定的..net
为何说B+-tree比B 树更适合实际应用中操做系统的文件索引和数据库索引?指针
1) B+-tree的磁盘读写代价更低orm
B+-tree的内部结点并无指向关键字具体信息的指针。所以其内部结点相对B 树更小。若是把全部同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的须要查找的关键字也就越多。相对来讲IO读写次数也就下降了。blog
举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点须要2个盘快。而B+ 树内部结点只须要1个盘快。当须要把内部结点读入内存中的时候,B 树就比B+ 树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。索引
2) B+-tree的查询效率更加稳定
因为非终结点并非最终指向文件内容的结点,而只是叶子结点中关键字的索引。因此任何关键字的查找必须走一条从根结点到叶子结点的路。全部关键字查询的路径长度相同,致使每个数据的查询效率至关。
B*
B*-tree是B+-tree的变体,在B+树的基础上(全部的叶子结点中包含了所有关键字的信息,及指向含有这些关键字记录的指针),B*树中非根和非叶子结点再增长指向兄弟的指针;B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2)。
B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增长新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,因此它不须要指向兄弟的指针。
B*树的分裂:当一个结点满时,若是它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(由于兄弟结点的关键字范围改变了);若是兄弟也满了,则在原结点与兄弟结点之间增长新结点,并各复制1/3的数据到新结点,最后在父结点增长新结点的指针。
因此,B*树分配新结点的几率比B+树要低,空间使用率更高;
总结:
B树:有序数组+平衡多叉树;
B+树:有序数组链表+平衡多叉树;
B*树:一棵丰满的B+树。
详情看出处: