什么是B+树
在介绍B+树之前让我们来先了解什么是B-树吧!
B-Tree是为了磁盘外存储设备设计的一种平衡查找树。
B-Tree结构可以让系统高效的查找数据所在的磁盘。
一颗m阶的B-Tree有如下特性:
1.每个节点最多有m个子节点。
2.除根节点和叶子节点之外,其它每个节点至少有Ceil(m/2)个孩子。
3.若根节点不是叶子节点,至少有2个孩子
4.所有叶子结点都在同一层,且不包含其他关键字信息
- 每个非终端节点包含n个关键字信息(P0,P1,…Pn, k1,…kn)
- 关键字的个数n满足:ceil(m/2)-1 <= n <= m-1
- ki(i=1,…n)为关键字,且关键字升序排序。
- Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1)
B-Tree中的每个节点根据实际情况可以包含大量的关键字信息和分支,如下图所示为一个3阶的B-Tree:
(图片来自https://blog.youkuaiyun.com/qq_21993785/article/details/80576642)
好了让我们开始介绍B+树吧!
B+Tree是对B-Tree树的一种优化。不知道看官老爷们有没有发现每个结点中不仅包含key值,还包含data值,而且每个结点的存储空间有限,当key值很多时树的深度就会很大,增加查询磁盘I/O次数(衡量数据查询相率的一种指标)。
B+Tree相对于B-Tree有几点不同
1.非叶节点只存储键值信息。
2.所有叶子节点之间都有一个链表指针。
3.数据记录都存放在叶子节点中
B+Tree简单结构如下:
一般B+树有两个链表,一个指针指向根节点(innodb常驻内存中),另一个指向最左边的叶子结点。基于这种结构可以对B+Tree进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根结点开始查找。
简单介绍红黑树
红黑树(Red Black Tree)是一种自平衡的二叉查找树。除了符合二叉查找树的基本特性,它还具有下列的附加特性:
1.节点是红色或黑色。
2.根节点是黑色。
3.每个叶子节点都是黑色的空节点(NIL节点)。
4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
为什么mysql索引底层使用的是B+树存储,而不是红黑树吗?
说了这么多本文的主角终于要登场了!
红黑树等平衡树也可以用来实现索引,但是文件系统及数据库系统普遍采用 B+ Tree 作为索引结构,这是因为使用 B+ 树访问磁盘数据有更高的性能。
(1)系统从磁盘中读取数据是以磁盘块(block)为单位的,位于同一磁盘的数据都会被读取出来而不是需要什么就读取什么。
InnoDB引擎是以页为磁盘管理的最小单位,默认大小为16k,当然也可以自己调整,而磁盘中的块往往没有这么大的空间,所用InnoDB一般会申请连续的多个块来达到页的大小16k。数据库系统通常将索引的一个节点设置为一个页的大小,这样每个节点只需一次I/O就可以完全载入。如果数据不在同一个磁盘上,那么通常需要移动磁臂来寻找柱面,效率低下。
(2)因为B+树非页节点都用来存储键值,数据都存储在叶节点中,所以当数据库记录很多时,B+树的深度也不会很大,所以I/O查询次数也不会很多最多h-1次(根节点常驻内存)。B+ 树相对于红黑树有更低的树高,进行寻道的次数与树高成正比,在同一个磁盘块上进行访问只需要很短的磁盘旋转时间,所以 B+ 树更适合磁盘数据的读取。