Mysql索引 1:二叉树到B+树的进化过程

发布时间 2023-09-22 11:13:30作者: 小韩小寒,不能喊烦

什么是索引?

在关系数据库中,索引是一种数据结构,他将数据提前按照一定的规则进行排序和组织,能够帮助快速定位到数据记录的数据,加快数据库表中数据的查找和访问速度。

像书籍的目录、文件夹、标签 、房号... 都可以帮助我们快速定位,都可以视为索引。

能实现快速定位数据的一种存储结构,其设计思想是以空间换时间。

 

索引的种类?

mysql中的索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。

常见的索引分类有:

按照数据结构分类:B+tree索引 , Hash索引 , Full - rext索引

按照物理存储分类: 聚集索引 , 非聚集索引。

按字段特性分类:主键索引(primary key), 唯一索引(unique),普通索引(index),全文索引(fulltext)。

按字段个数分类:单列索引 , 联合索引 (也叫复合索引 , 组合索引)

 

常见索引数据结构和区别?

二叉树 , 红黑树 , B树 ,B+树       

区别:树的高度影响获取数据的性能(每个树点都是一次磁盘I/O)

1:二叉树

特点:每个节点最多有两个子节点,大在右,小在左,数据随机性情况下树杈越明显。

 

但是如果数据是顺序依次进入:

树的高度就会很高(形成一个链表结构),此时元素的查询效率就等于链表查询O(n),数据检索效率将会为低下

极端情况下,就是一个链表结构,此时元素的查找效率就等于链表查询O(n)。

 

2.红黑树(平衡二叉树)

虽通过自旋平衡,子节点会自动分叉为2个分支,从而减少树的高度,当数据有序插入时比二叉树数据检索性能更佳。

自旋平衡简而言之平衡策略可以简单概括为三种:左旋转,右旋转,变色。(这里主要讲索引,红黑树自旋底层原理后续另写一篇)

但是如果数据量过大,节点个数就越多,树高度也会增高(也就是树的深度越深),增加磁盘I/O次数,影响查询效率。

3.B树

B树的出现可以解决树高度的问题。之所以是B树,而并不是名称中“XXX二叉树”,就是它不再限制一个父节点中只能有两个子节点,而是允许M个子节点(M>2)。

不仅如此,B树的一个节点可以存储多个元素,相比较之前那些二叉树数据结构又将整体的树高度降低了。

 

B树的节点可以包含有多个子节点,所以B树是一颗多叉树,他的每个节点包含的最多子节点数量的称为B树的阶。

当一颗3阶的B树查找7这个元素的流程是怎么样的?

先从根节点出发。判断7在4和8之间,根据P2存储指针6的节点,判断7大于6,最后指针找到叶子节点。也就找到有匹配7的键值。

 

可以发现一颗3阶的B树在查找叶子节点时,由于树高度只有3,所以查找过程最多只需要3次的磁盘I/O操作。

数据量不大时可能不太真切,但是数据量大时,节点也会随着增多;此时如果前面的自平衡二叉树的场景下,由于二叉树只能最多2个叶子节点的约束,也只能纵向去扩展子节点,树的高度会很高,意味着需要更多的操作磁盘I/O次数。

而B树则可以通过横向扩展节点从而降低树的高度。所以效率自然要比二叉树更高。(直白说就是变矮胖了)

虽然B树现在满足了所有的条件:减少磁盘的I/O操作,同时支持按照区间查找。但是,虽然B树支持按区间查找,但是效率并不高。

例如上面的例子当中,B树能高效通过等值查询15这个值,但是不方便查询出一个区间内3~10区间内所有的数结果。因为当树做范围查询时需要遍历需要使用中序遍历,那么父节点和子节点也就需要不断的来回切换涉及了多个节点会给磁盘I/O带来了很多负担。

 

4.B+tree树

在Mysql中为什么会选用B+tree做为数据索引呢?

B+tree是在B树基础上的一种优化,其更适合做存储索引结构,在B+tree中,非叶子节点上仅存储键值,不存储数据;而所有的数据记录均存储在叶子节点上,并且数据是按照顺序排列的。

此外在B+tree中各个数据页之间是用过双向链表连接的,B+tree结构图如下:

 

 

B树和B+树的区别,Mysql为什么要选择B+树做为默认索引的数据结构呢?

 

B+tree结构实现数据索引具体优点如下:

1:非叶子节点上可以存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树也就变得更矮更胖。这样查找数据进行的磁盘I/O的次数大大减少,数据查询的效率也会更快。

2:所有数据记录都有序存储在叶子节点上,就会使得范围查找,排序查找,分组查找,去重查找变得异常简单。

3:数据页之间,数据记录之间都是通过链表连接的,有了这个结构的支持就可以方便在数据查询后进行升序或者降序的操作。