一、m阶B树
1、根节点至少有两个子女
2、每个中间节点都包含k-1个元素和k个孩子,其中m/2<=k<=m
3、每一个叶子节点都包含k-1个元素,其中m/2<=k<=m
4、所有的叶子节点都位于同一层
5、每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分
优势:自平衡,它能够维持多路平衡。
B树主要应用于文件系统以及部分数据库索引,比如著名的非关系型数据库MongoDB,而大部分关系型数据库,比如MySql,则使用B+树作为索引。
二、m阶B+树
1、有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来作为索引,所有数据都保存在叶子节点
2、所有的叶子节点中包含了全部元素的信息,及指向这些元素记录的指针,且叶子节点本身依关键字的大小自小而大顺序链接
3、所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素
优势:
1、单一节点存储更多的元素,使得查询的IO次数更少
2、所有查询都要查找到叶子节点,查询性能稳定
3、所有叶子节点形成有序链表,便于范围查询
卫星数据:索引元素所指向的数据记录,比如数据库中的某一行
在B树中,无论中间节点还是叶子节点,都带有卫星数据,而在B+树中,只有叶子节点带有卫星数据,其余中间节点仅仅是索引,没有任何数据关联。
在数据库的聚集索引中,叶子节点直接包含卫星数据;在非聚集索引中,叶子节点带有指向卫星数据的指针。
聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物理顺序。
非聚集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
为什么MongoDB采用B树索引,而MySql用B+树作索引?
先从数据结构的角度来答。
这就决定了B+树更适合用来存储外部数据,也就是所谓的磁盘数据。
从Mysql(Inoodb)的角度来看,B+树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。
那么Mysql如何衡量查询效率呢?磁盘IO次数,B-树(B类树)的特定就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,当查询数据的时候,最好的情况就是很快找到目标索引,然后读取数据,使用B+树就能很好的完成这个目的,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时啊!),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。这是优点之一。
另一个优点是什么,B+树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来。这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。
至于MongoDB为什么使用B-树而不是B+树,可以从它的设计角度来考虑,它并不是传统的关系性数据库,而是以Json格式作为存储的nosql,目的就是高性能,高可用,易扩展。首先它摆脱了关系模型,上面所述的优点2需求就没那么强烈了,其次Mysql由于使用B+树,数据都在叶节点上,每次查询都需要访问到叶节点,而MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。
总体来说,Mysql选用B+树和MongoDB选用B-树还是以自己的需求来选择的。