了解MySQL底层的数据结构

129 阅读4分钟

说到数据结构我们会想到数组、链表、列表、队列、树、图等,今天主要讲的是MySQL底层的索引数据结构是采用什么。是哈希表、二叉树还是红黑树还是B+树? 我们在对一张表建索引的时候可以选择那些数据结构作为我们的存储,看下图

图片.png

可以选择哈希表和B+树进行存储,那么他们之间有什么区别吗,采用哈希表和采用B+树进行存储有什么优势呢,有什么缺点呢? 简单介绍下:

哈希表(如图)

图片.png

哈希表: 对索引的key进行一次hash计算就可以定位出具体的数据存储位置,比B+ 树索引更高效 但是缺点是,仅能满足 “=”,“IN”,不支持范围查询并且还存在hash冲突问题。

什么是B+树? 和我们知道的B树有啥区别吗? 先简单介绍两者之间的区别,也是面试经常问题面试题

B树:

(1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;

(2)子节点数:非叶节点(根节点和枝节点)的子节点数 >1、且子节点数量<=M 、且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);

(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);

(4)所有叶子节点均在同一层、叶子节点除了包含了关键字 和 关键字记录的指针外,也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子;

图片.png

B+树:

(1)B+树的非叶子节点不保存具体的数据,而只保存关键字的索引,而所有的数据最终都会保存到叶子节点。因为所有数据必须要到叶子节点才能获取到,所以每次数据查询的次数都一样,这样一来B+树的查询速度也就会比较稳定,而B树的查找过程中,不同的关键字查找的次数很有可能都是不同的(有的数据可能在根节点,有的数据可能在最下层的叶节点),所以在数据库的应用层面,B+树就显得更合适。

(2)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。因为叶子节点都是有序排列的,所以B+树对于数据的排序有着更好的支持。

(3)非叶子节点的子节点数=关键字数(来源百度百科)(根据各种资料 这里有两种算法的实现方式,另一种为非叶节点的关键字数=子节点数-1(来源维基百科),虽然他们数据排列结构不一样,但其原理还是一样的Mysql 的B+树是用第一种方式实现);

图片.png

  • B+树和B树的对比

1、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定。

2、B+树天然具备排序功能: B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。

3、B+树全节点遍历更快: B+树遍历整棵树只需要遍历所有的叶子节点即可,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

B树相对于B+树的优点是,如果经常访问的数据离根节点很近,而B树非叶子节点本身存有关键字和数据,所以在查询这种数据检索的时候会要比B+树快。

介绍完以上数据结构后,那么在MySQL中目前常用的就是B+树,因为有先天性的有序、获取数据快的优势,那么我们在实际上查找数据的时候走索引就很快就能获取到我们想要的数据了。再者,因为B+树的叶子节点是链表形式的,当我们需要Select * from 某张表的时候,就可以直接定位到叶子节点获取所有数据,这也是为什么MySQL采用这种数据结构的原因。

完毕!