MySQL索引使用的数据结构:B-Tree和B+Tree

MyISAM是MySQL 5.5之前版本默认的存储引擎,从5.5之后,InnoDB开始成为MySQL默认的存储引擎。

MyISAM使用B-Tree实现主键索引、唯一索引和非主键索引。

InnoDB中非主键索引使用的是B-Tree数据结构,而主键索引使用的是B+Tree。

本文就是对这两种数据结构做简单的介绍。

1. B-Tree

B-Tree不是“B减树”,而是“B树”。

这里参考了严蔚敏《数据结构》对B-Tree的定义:

一棵m阶的B-Tree,或者为空树,或者满足下列特性:
1.树中每个结点至多有m棵子树;
2.若根结点不是叶子结点,则至少有两棵子树;
3.除根节点之外的所有非终端结点至少有[m/2]棵子树;
4.所有非终端结点中包含下列信息数据:
(n,A0,K1,A1,K2,A2……Kn,An)
其中,n为关键字的数目,K(i)为关键字,且K(i) < K(i+1), Ai为指向子树根结点的指针,且指针A(i-1)所指子树中所有结点的关键字均小于Ki,Ai所指子树中所有结点的关键字均大于Ki;
5.所有叶子结点都出现在同一层次上;

下面通过一个例子解释一下B-Tree的查找过程。

这是一棵4阶的B-Tree,深度为4。

假如在该图中查找关键字47,首先从根结点开始,根据根结点指针t找到*a结点,因为47大于 *a 结点的关键字35,所以会去A1指针指向的 *c结点继续寻找,因为 *c的关键字 43 < 要查找的47 < *c结点的关键字78,所以去 *c结点A1指针指向的 *g结点去寻找,结果在 *g结点中找到了关键字47,查找成功。

2. B+Tree

不同的存储引擎可能使用不同的数据结构存储,InnoDB使用的是B+Tree;那什么是B+Tree呢?
B+Tree是应文件系统所需而出的一种B-Tree的变型树,一棵m阶的B+树和m阶的B-树的差异在于:
1.有n棵子树的结点中含有n个关键字;
2.所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字的记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接;
3.所有的非终端结点可以看成是索引部分,结点中仅含有其子树(根结点)中的最大(或最小)关键字;

还是通过一个例子来说明。
MySQL索引使用的数据结构:B-Tree和B+Tree_第1张图片
这个例子中,所有非终端结点仅含有子树中最大的关键字。

因为叶子节点本身依据关键字的大小自小而大顺序链接,所以可以从最小关键字起顺序查找。也可以从根结点开始,进行随机查找。

在B+树中随机差找和在B-树中类似,以上图为例。假设要查找关键字51,现在根节点中比较,发现51<59,因为这里使用的是非终端结点的关键字是子树中最大的关键字,所以进入最大值为59的子结点(15\44\59)中查找,同理,因为44<51<59,所以进入P3指向的结点(51\59)中查找,然后命中关键字51,因为此结点(51\59)是叶子结点,所以查找终止,该结点包含指向数据的指针。

3.索引如何在B+Tree中组织数据存储

假设有如下表:
MySQL索引使用的数据结构:B-Tree和B+Tree_第2张图片
对于表中的每一行数据,索引中包含了last_name、first_name和dob列的值,下图展示索引是如何组织数据存储的:
MySQL索引使用的数据结构:B-Tree和B+Tree_第3张图片

索引对多个值进行排序的依据是定义索引时列的顺序。
(Allen Cuba 1960-01-01)结点左侧的指针指向[?,Allen Cuba 1960-01-01)的叶子页,(Allen Cuba 1960-01-01)和(Astaire,Angelina,1980-03-04)之间的指针指向[Allen Cuba 1960-01-01,Astaire Angelina 1980-03-04)的叶子页,以此类推。总之,每个指针指向的结点中的最小值就是该指针左侧的的值。

这种存储结构也说明了在定义多个列组成的多列索引中,为什么需要把重复率最低的列放到最左侧,因为这会减少比较的次数,查找起来更加高效。

4.索引为什么选用B树这种数据结构?
因为使用B树查找时,所用的磁盘IO操作次数比平衡二叉树更少,效率也更高。
为什么使用B树查找所用的磁盘IO操作次数比平衡二叉树更少?
大规模数据存储中,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于树的高度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下。那么我们就需要减少树的高度以提高查找效率。而平衡多路查找树结构B树就满足这样的要求。B树的各种操作能使B树保持较低的高度,从而达到有效减少磁盘IO操作次数。

参考资料:
《数据结构(C语言版)》
《Effective MySQL之SQL语句最优化》
《高性能MySQL》

你可能感兴趣的:(MySQL索引使用的数据结构:B-Tree和B+Tree)