MySQL数据库索引------B+树索引

        MySQL数据库是一种关系型数据库,主要涉及内容有表和集合,数据库是表,表是行和列的集合。当我们调用SELECT语句来查询表中的行时,得到的结果则是行和列的另一个集合,即另外一个表。这些抽象的概念,并不涉及数据库系统用来操作表中数据的底层表示。数据库管理系统的确能实现这些抽象概念,但依赖于实际硬件的具体实现会收到各种真实物理条件的约束。因此,查询需要占用一定的时间。而为表创建索引,可以加速查询。目前MySql使用的引擎是InnoDB存储引擎,它支持的索引包括:B+树索引、全文索引、哈希索引。本文主要介绍下比较常用的B+树索引。
        B+树索引是目前关系型数据库系统比较常用的一种索引,B+树索引的构造类似于二叉树,根据键值(Key Value)快速找到数据。(此处要注意下:B+树中的B不是代表二叉(binary),而是代表平衡(balance),因为B+树是从最早的平衡二叉树演化而来,但是B+树不是一个二叉树)。为了更好的了解B+树索引,有必要了解下与之相关的算法与数据结构。


       1、二分查找法:

        也称为折半查找法,用来查找一组有序的记录数组中的某一记录,其基本思想是:将记录按有序化(递增或递减)排列,在查找过程采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,则将待查找序列缩小为左半部分,否则为有半部分。通过一次比较,将查找区间缩小一半。

       如上图所示,查找记录48这条记录,只需要查找三次即可。如果是顺序查找需要查找8次。对于上面10个数的顺序平均查找次数为:(1+2+3+4+5+6+7+8+9+10)/10=5.5/次,二分查找平均查找次数为:(4+3+2+4+3+1+4+3+2+3)/10=2.9/次。所以说二分查找的效率平均来说是高于顺序查找的效率的。
        2、二叉查找树和平衡二叉树:
        二叉查找树是一种经典的数据结构,如下图展示了一颗二叉查找树,数字代表每个节点的键值,并且左子树的键值总是小于根的键值,右子树的键值总是大于根的键值。如果对二叉查找树查找某节点值,例如查找键值为5的节点,首先查到根节点键值,发现根键值6大于5,因此查找跟节点的左子树,发现5大于3,再找其右子树,一共查找了三次。

        然而并不是所有的二叉查找树的查询效率相对顺序查询高,例如下图的二叉查找树的查询效率跟顺序查找相差无几。因此为了保证二叉查找树的性能,必须要尽可能的保证二叉查找树的平衡,即一种新的数据结构,平衡二叉树:首先符合二叉查找树的定义,其次必须满足任何节点的两个子树高度最大差为1。

3、B+树:
       B+树是通过二叉查找树,再由平衡二叉树,B树演化而来的,是为磁盘或其他直接存储设备设计的一种平衡查找树。在B+树中,所有的记录节点都是按照键值的大小顺序存放在同一层的叶子节点上,由各叶子节点指针进行链接,如下图所示:

3.1、B+树插入
B+树的插入操作必须保证插入后叶子节点中的记录依然排序,插入操作必须要考虑以下三种情况:
1) 叶子节点和内部索引节点都未满的情况下,可以直接将记录插入到叶子节点。例如将记录28键值插入B+树中,如下图所示:

2) 叶子节点已满,但是内部索引节点未满的情况下,首先要拆分叶子节点,将中间的节点放入到内部索引节点;其次将小于中间节点的记录放左边,大于或者等于中间节点的记录放在右边。例如插入记录70键值,如下图所示:

3) 叶子节点和内部索引节点都满的情况下,首先要拆分叶子节点,将中间的节点放入到内部索引节点;其次将小于中间节点的记录放左边,大于或者等于中间节点的记录放在右边;再次内部索引节点,将小于中间节点的放左边,大于中间节点放右边;最后中间节点放入上一层内部索引节点。例如,再继续插入95键值,如下图所示:

3.2、B+树删除:
       B+ 树使用填充因子来控制树的删除变化,50%是填充因子可设的最小值。B+树的删除操作同样必须保证删除后叶子节点中的记录依然排序,同插入一样,B+树的删除操作同样需要考虑以下三种情况,但是与插入不同的是,删除根据填充因子的变化来衡量。
1) 叶子节点小于填充因子和中间节点小于填充因子情况下,首先需要合并叶子节点和它的兄弟节点;其次更新内部索引页,合并内部索引页和它的兄弟节点。
2) 叶子节点大等于填充因子和中间节点小于填充因子情况下,需要合并叶子节点和它的兄弟节点,同时更新内部索引页。
3) 叶子节点大于等于填充因子和中间节点大于等于填充因子情况下,可以直接将记录从叶子节点删除,如果该节点还是内部索引页的节点,用该节点的右节点代替。
B+树索引:
        通过前面介绍了解了B+树的数据结构及其一般操作,B+树索引的本质就是B+树在数据库中的实现。但是B+树索引在数据库中有个特点就是高扇出性,因此在数据库中,B+树的高度一般都在2-4层,这也就是说查找某一键值的行记录时最多只需要2到4次IO,是不是效率很高。B+树索引可以分为聚集索引(clustered index)和辅助索引(secondary index),但是不论哪种索引,其内部都是B+树,即高度平衡的,叶子节点存放着所有的数据。但是不同的是聚集索引叶子节点存放的是一整行的记录。
聚集索引是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性也决定了索引组织表中数据也是索引的一部分,每个数据页都通过一个双向链表来进行连接,同时也有个好处,就是对于主键的排序查找和范围查找速度非常快。如下图所示:

辅助索引,其叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签,用于告诉InnoDB存储引擎哪里可以找到与索引对应的行数据。由于InnoDB存储引擎表就是索引组织表,因此InnoDB存储引擎的辅助索引的书签就是相应行数据的聚集索引键,如下图所示:

辅助索引的存在并不影响数据在聚集索引的组织,因此每张表可以有多个辅助索引。当通过辅助索引来搜索数据时,InnoDB存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,再通过主键查找一整行记录。
结束语:本文介绍了B+树索引以及相关的数据结构,希望可以加深大家对B+树索引的理解,如有错误或者不全面地方请及时指出,谢谢阅读。

发布了18 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/chuhx/article/details/103823692