MySql知识点回顾:索引(一)B树和B+树

(一)索引的定义

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。

我们知道,数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化。最基本的查询算法当然是顺序查找(linear search),这种复杂度为O(n)的算法在数据量很大时显然是糟糕的,好在计算机科学的发展提供了很多更优秀的查找算法,例如二分查找(binary search)、二叉树查找(binary tree search)等。如果稍微分析一下会发现,每种查找算法都只能应用于特定的数据结构之上,例如二分查找要求被检索数据有序,而二叉树查找只能应用于二叉查找树上,但是数据本身的组织结构不可能完全满足各种数据结构(例如,理论上不可能同时将两列都按顺序进行组织),所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。

目前大部分的数据库系统及文件就是采用B-Tree或其变种B+Tree作为索引结构的。例如MySql就是使用B+Tree作为索引结构,而 MongoDB 默认的存储引擎,WiredTiger 使用 B 树作为索引底层的数据结构。
接下来我们就简单的分析一下B树和B+树

(二)B树和B+树

B树的原则:

一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足以下性质:
1、根节点至少有2个孩子
2、每个非根节点至少有M/2-1(上取整)个关键字,至多有M-1个关键字,并且以升序排列
例如:当M=3的时候,至少有3/2=1.5,向上取整等于2,2-1=1个关键字,最多 是2个关键字
3、每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子
例如:当M=3的时候,至少有3/2=1.5,向上取整等于2个孩子。最多有3个孩 子。
4、key[i]和key[i+1]之间的孩子节点的值介于key[i]、key[i+1]之间
所有的叶子节点都在同一层

接下来我们就来模拟一下B树插入的流程:

B树插入流程:

这里我是通过Data Structure Visualizations进行模拟的:
这里我们新建一颗3阶得B树,插入的数据分别为(按顺序插入):58 24 12 68 72 88 46 67
这里先看一下这棵树最终的样子:
在这里插入图片描述

1、插入58
在这里插入图片描述
(1)如果树为空,直接插入新节点中,该节点为树的根节点。

2、插入24
在这里插入图片描述
3、插入12
在这里插入图片描述
(1)注意这里插入12的时候,按照插入排序的思想,将12插入到序列当中。
(2)插入之后,发现该节点不满足B树原则2中的至少有1个关键字,至多有2个关键字,所以这个时候就会进行分裂。
(3)分裂的过程包括:找到目前该节点中中间的位置,给一个新节点,将中间位置的数据搬移到新节点当中,将中间位置数据搬移到父节点中,然后将节点连接好。

4、插入68
在这里插入图片描述
(1)首先找到根节点(0024)
(2)68>24所以这里继续去查询24的右侧节点
(3)然后找到叶子节点(0058)判断发现68>58,然后插入到当前节点当中。
(4)插入完成后,会检测该节点是否满足B树的原则。
满足:插入结束

5、插入72
在这里插入图片描述
(1)首先找到根节点(0024)
(2)发现插入的数据72>24,所以需要继续去遍历右子节点
(3)找到右子节点(0058,0068),然后插入数据72
(4)插入完成后,会检测当前该节点是否满足B树的原则
不满足:对当前该节点进行分裂(因为这颗是3阶B树,当前节点至少存在1个关键字,最多是2个关键字)
(5)分裂的操作:找到当前节点(0058,0068,0072)的中间位置,将中间的元素往父节点中进行插入,而左右两侧的元素重新指向父节点

6、插入88
在这里插入图片描述
(1)首先找到根节点(0024,0068),因为88>68>24,所以这里直接找到右子节点
(2)右子节点中(0072),因为这里88>72,所以直接插入到72的右侧,插入后发现符合B树的原则

7、插入99
在这里插入图片描述
(1)这里首先找到根节点(0024,0068)进行比较,发现99>68>24。所以继续去右侧的子节点中进行查询
(2)然后就到了(0072,0088)的节点当中,发现99>88>72,所以这里会选择继续去查询当前节点的右侧子节点,但因为这里已经是叶子节点了,所以在当前节点当中并没有子节点了,所以会直接插入在当前节点当中,于是就变成了(0072,0088,0099)。插入后发现不符合B树的原则,所以就会进行分裂操作
(3)对(0072,0088,0099)节点进行分裂操作,取当前节点中的中间节点(0088)移动到父节点当中,当前节点的左侧节点和右侧节点依然指向(0088)。
(4)当(0088)移动到父节点当中时,根节点就变成了(0024,0068,0099),所以要对当前节点再进行分裂。因为此节点为根节点,没有父节点了,所以这里就取当前节点中的中间节点作为根节点,然后左侧节点和右侧节点重新指向根节点。

B+树:

B+树和二叉树、平衡二叉树一样,都是经典的数据结构。B+树由B树和索引顺序访问方法演化而来,但是在现时使用的过程中几乎已经没有使用B树的情况了。
B+树是为磁盘或其他直接存取辅助设备设计的一种平衡查找树。所有记录节点都是按键值的大小顺序存放在同一层的叶子节点上,由各叶子节点指针进行连接。

B+树的插入情况

在这里插入图片描述

这里我们初始新建一颗3阶得B+树,插入的数据分别为(按顺序插入):58 24 12 68 72 88 46 67

这里看一下这棵树初始化的样子:
在这里插入图片描述
那么现在我们就在这颗初始化的B+树上继续进行插入操作
这里我们首先插入60

在这里插入图片描述
1、这里在插入60的时候,我们首先可以看到与B树的访问顺序相同,先从根节点(0058)中去进行访问,通过比较60>58,这里继续去找子节点(0068,0072)。
2、这里通过比较(0068,0072)的当前节点上的值,发现60<68<72,好的这里就继续去左侧的子节点进行遍历。
3、这里到了节点(0058,0067)通过比较发现58<60<67,这里发现60处于中间位置,理应继续去遍历中间的子节点,但是现在发现当前节点已经是叶子节点了。然后就会判断当前节点是否符合B+树的原则。
4、发现当前节点不符合B+树的原则,所以就会再一步进行分裂操作。
在这里插入图片描述
5、当前节点为(0058,0060,0067)首先取中间节点60,转移到父节点当中,因为B+树的叶子节点当中包含了所有的元素,这里就会在叶子节点当中添加上60这个元素,并且把(0058)和(0060,0067)指向(0060,0068,0072)的节点。
6、这里发现(0060,0068,0072)的节点不符合B+树的原则,就会继续进行分裂,(0060,0068,0072)的中间节点为0068,这里会把0068向上转移到父节点当中,并把当前节点的0060作为左子节点,0072作为右子节点重新指向0068。
7、到此为止,发现整棵树符合B+树的原则,插入完毕。

B+树的特性

1、所有关键字都出现在叶子节点的链表中(稠密索引),且链表中的节点都是有序的。
2、不可能在非叶子节点中命中。
3、非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储数据的数据层。
4、更适合文件索引系统

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值