MySQL-数据页的结构,十年开发经验Java架构师

表中记录的行格式示意图如下所示:在这里插入图片描述

关于图中具体字段的含义解释如下:

  • 预留位1:没有使用

  • 预留位2:没有使用

  • delete_mask

这个属性标记着当前记录是否被删除,占用1个二进制位,值为 0 的时候代表记录并没有被删除,为 1 的时 候代表记录被删除掉了。

  • min_rec_mask

B+树的每层非叶子节点中的最小记录都会添加该标记。

  • n_owned

表示当前记录拥有的记录数。

  • head_no

这个属性表示当前记录在本 页 中的位置

  • record_type

这个属性表示当前记录的类型,一共有4种类型的记录, 0 表示普通记录, 1 表示B+树非叶节点记录, 2 表 示最小记录, 3 表示最大记录。

  • next_record

  • 它表示从当前记录的真实数据到下一条记录的真实数据的地址偏移量。

  • 下一条记录 指得并不是按照我们插入顺序的下一条记录,而是按照主键值由小到大的顺序的下一条记录。而且规定 Infimum记录(也就是最小记录) 的下一条记录就是本页中主键值最小的用户记录,而本页中主键值最大的用户记录的下一条记录就是 Supremum记录(也就是最大记录)。

为了更形象的表示一下这个 next_record 起到的作用,我们用箭头来替代一下next_record 中的地址偏移量,从图片可以看出记录按照主键从小到大的顺序形成了一个单链表。最大记录 的 next_record 的值为 0 ,这也就是说最大记录是没有 下一条记录 了,它是这个单链表中的最后一个节点。在这里插入图片描述

Free Space 空闲空间


页中尚未使用的空间

Page Directory 页目录


页中的某些记录的相对位置。

现在我们了解了记录在页中按照主键值由小到大顺序串联成一个单链表,那如果我们想根据主键值查找页中的某条记录该咋办呢?比如说这样的查询语句:

SELECT * FROM page_demo WHERE c1 = 3;

最笨的办法:从 Infimum 记录(最小记录)开始,沿着链表一直往后找,总有一天会找到,在找的时候还能投机取巧,因为链表中各个记录的值是按照从小到大顺序排列的,所以当链表的某个节点代表的记录的主键值大于你想要查找的主键值时,你就可以停止查找了,因为该节点后边的节点的主键值依次递增。

我们来看一下一种比较简单的方法,引入目录的概念,也就是索引的由来,具体过程如下:

  1. 将所有正常的记录(包括最大和最小记录,不包括标记为已删除的记录)划分为几个组。

  2. 每个组的最后一条记录(也就是组内最大的那条记录)的头信息中的n_owned属性表示该记录拥有多少条记录,也就是该组内共有几条记录。

  3. 将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到靠近页的尾部的地方,这个地方就是所谓的page Directory ,也就是页目录.页面目录中的这些地址的偏移量被称为槽(Slot),所以这个页面目录就是由组成的。

比方说现在的 page_demo 表中正常的记录共有6条, InnoDB 会把它们分成两组,第一组中只有一个最小记录,第二组中是剩余的5条记录,看下边的示意图:

在这里插入图片描述

从这个图中我们需要注意这么几点:

  • 现在 页目录 部分中有两个槽,也就意味着我们的记录被分成了两个组,槽1中的值是112 ,代表最大记录的地址偏移量(就是从页面的0字节开始数,数112个字节); 槽0 中的值是 99 ,代表最小记录的地址偏移量。

  • 注意最小和最大记录的头信息中的 n_owned 属性:

  • 最小记录的 n_owned 值为 1 ,这就代表着以最小记录结尾的这个分组中只有 1 条记录,也就是最小记录本身。

  • 最大记录的 n_owned 值为 5 ,这就代表着以最大记录结尾的这个分组中只有 5 条记录,包括最大记录本身还有我们自己插入的 4 条记录。

分组(槽)的依据

对于最小记录所在的分组只能有 1 条记录, 最大记录所在的分组拥有的记录条数只能在 1~8 条之间,剩下的分组中记录的条数范围只能在是 4~8 条之间。

在这里插入图片描述

  • 初始情况下一个数据页里只有最小记录和最大记录两条记录,它们分属于两个分组。

  • 之后每插入一条记录,都会从 页目录 中找到主键值比本记录的主键值大并且差值最小的槽,然后把该槽对应的记录的 n_owned 值加1,表示本组内又添加了一条记录,直到该组中的记录数等于8个。

  • 在一个组中的记录数等于8个后再插入一条记录时,会将组中的记录拆分成两个组,一个组中4条记录,另一个5条记录。这个过程会在 页目录 中新增一个 槽 来记录这个新增分组中最大的那条记录的偏移量。

查找槽的位置

使用二分法快速查找

  1. 通过二分法确定该记录所在的槽,并找到该槽中主键值最小的那条记录。

  2. 通过记录的 next_record 属性遍历该槽所在的组中的各个记录。

实例如下:

在这里插入图片描述

4个槽的编号分别是: 0 、 1 、 2 、 3 、 4 ,所以初始情况下最低的槽就是 low=0 ,最高的槽就是high=4 。比方说我们想找主键值为 6 的记录,过程是这样的:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档

祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!

感谢大家的支持!!

image.png

[外链图片转存中…(img-ul4f4WOQ-1711777190351)]

最后

这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档

祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!

感谢大家的支持!!

[外链图片转存中…(img-c5ruJmPw-1711777190351)]

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值