MaSks要加油丫
发布于 2025-02-27 / 13 阅读
0
0

Mysql索引递进之路_03

一、索引迭代

上文提到目录项可以使用二分法的方式快速定位到目标目录项,进而找到数据页位置。

实际操作中,数据页只有16KB大小,随着数据页越来越多,数据目录项也会越来越多,底层连续空间存储的压力就会越来越大。还有一种情况,如果某数据页后期删除不要了,或者有数据新增,意味着数据目录项也需要删除或新增,由于数据项是连续存储的,所以需要不断移动数据目录项。

这么看,数据目录项连续存储不是很靠谱。

那么,如果让数据目录项也通过单向链表逻辑连接呢,而不必要刻意保证在磁盘中物理顺序连接。

由此,数据目录项记录页应运而生。

① 迭代1次:目录项纪录的页

我们把前边使用到的目录项放到数据页中的样子就是这样:

从图中可以看出来,我们新分配了一个编号为30的页来专门存储目录项记录。这里再次强调目录项记录和普通的用户记录的不同点:

  • 目录项记录的record_type值是1,而普通用户记录的record_type值是0。

  • 目录项记录只有主键值和页的编号两个列,而普通的用户记录的列是用户自己定义的,可能包含很多列,另外还有InnoDB自己添加的隐藏列。

  • 了解:记录头信息里还有一个叫min_rec_mask的属性,只有在存储目录项记录的页中的主键值最小的目录项记录的min_rec_mask值为1,其他别的记录的min_rec_mask值都是0。

相同点:两者用的是一样的数据页,都会为主键值生成Page Directory(页目录),从而在按照主键值进行查找时可以使用二分法来加快查询速度。

现在以查找主键为20的记录为例,根据某个主键值去查找记录的步骤就可以大致拆分成下边两步:

  1. 先到存储目录项记录的页,也就是页30中通过二分法快速定位到对应目录项,因为 12 < 20 < 209 ,所以定位到对应的记录所在的页就是页9。

  2. 再到存储用户记录的页9中根据二分法快速定位到主键值为20的用户记录。

② 迭代2次:多个目录项纪录的页

从图中可以看出,我们插入了一条主键值为320的用户记录之后需要两个新的数据页:

  • 为存储该用户记录而新生成了页31。

  • 因为原先存储目录项记录的页30的容量已满(我们前边假设只能存储4条目录项记录),所以不得不需要一个新的页32来存放页31对应的目录项。

现在因为存储目录项记录的页不止一个,所以如果我们想根据主键值查找一条用户记录大致需要3个步骤,

以查找主键值为20的记录为例:

  1. 确定目录项记录页我们现在的存储目录项记录的页有两个,即页30和页32,又因为页30表示的目录项的主键值的范围是 [1, 320) ,页32表示的目录项的主键值不小于 320 ,所以主键值为20的记录对应的目录项记录在页30中。

  2. 通过目录项记录页确定用户记录真实所在的页。在一个存储目录项记录的页中通过主键值定位一条目录项记录的方式说过了。

  3. 在真实存储用户记录的页中定位到具体的记录。

③ 迭代3次:目录项记录页的目录页

如图,我们生成了一个存储更高级目录项的页33,这个页中的两条记录分别代表页30和页32,如果用户记录的主键值在[1, 320)之间,则到页30中查找更详细的目录项记录,如果主键值不小于320的话,就到页32中查找更详细的目录项记录。

我们可以用下边这个图来描述它:

这个数据结构,它的名称是B+树。

二、B+Tree

B+Tree,树层次越低,io次数越少!

一个B+树的节点其实可以分成好多层,规定最下边的那层,也就是存放我们用户记录的那层为第0层,之后依次往上加。之前我们做了一个非常极端的假设:存放用户记录的页最多存放3条记录,存放目录项记录的页最多存放4条记录。其实真实环境中一个页存放的记录数量是非常大的,假设所有存放用户记录的叶子节点代表的数据页可以存放100条用户记录,所有存放目录项记录的内节点代表的数据页可以存放1000条目录项记录,那么:

  • 如果B+树只有1层,也就是只有1个用于存放用户记录的节点,最多能存放100条记录。

  • 如果B+树有2层,最多能存放1000×100=10,0000条记录。

  • 如果B+树有3层,最多能存放1000×1000×100=1,0000,0000条记录。

  • 如果B+树有4层,最多能存放1000×1000×1000×100=1000,0000,0000条记录。相当多的记录!!!

你的表里能存放100000000000条记录吗?所以一般情况下,我们用到的B+树都不会超过4层,那我们通过主键值去查找某条记录最多只需要做4个页面内的查找(查找3个目录项页和一个用户记录页),又因为在每个页面内有所谓的Page Directory(页目录),所以在页面内也可以通过二分法实现快速定位记录。


评论