一、页目录和槽

接上一篇,现在知道记录在页中按照主键大小顺序串成了单链表。

那么我使用主键查询的时候,最顺其自然的办法肯定是从第一条记录,也就是 Infrimum 记录开始,一直向后找,只要存在总会找到。这种在数据量少的时候还好说,一旦数据多了,遍历耗时一定非常长。

于是,作者又想到了一个好办法,灵感来自于书本中的目录。我们翻书的时候想查找一些内容,就会去查看目录,然后直接确定好内容所在的页码。

那么对于 InnoDB 来说,过程如下:

  • 将所有正常的记录划分为几个组,这里包括那 2 条虚拟记录,但是不包含已经被移除到垃圾链表的记录。
  • 每个组内最后一条记录(也就是最大的那条)就是“大哥”,其他记录都是“小弟”,而“大哥”记录的头信息中的 n_owned 属性表示该组内共有几条记录。
  • 将每个组中最后一条记录在页面中的地址偏移量单独提取出来,按顺序存储到靠近页尾部的地方。

这个地方就是页目录 Page Directory。而上述的地址偏移量就是该记录的真实数据与页面中第 0 个字节之间的距离,这些地址偏移量被称为槽。

每个槽占用 2 字节,页目录就是由多个槽组成。

二、页目录的规定

在上一篇中,创建的表里存在 4 条数据,那么在页中还要算上 Infimum 和 Supremum,共 6 条记录。

这时候 InnoDB 会把它们分出 2 个组:

  • 第一组:只有一个 Infimum 记录
  • 第二组:剩下的 5 条记录

每个槽中,存放着每个组里最大的那条记录所在页面中的地址偏移量。

从图中,需要关注页目录的一些点:

  • 页目录有 2 个槽,说明记录被分为 2 个组。
  • Infimum 记录的 n_owned 属性值为 1,而 Supremum 的为 5。

为什么这 6 条记录要这样分?因为作者对于每组中的记录数量有规定:

  • 对于 Infimum 所在的分组只能有 1 条记录。
  • Supremum 所在的分组只能在 1~8 条之间。
  • 剩下的分组,记录条数范围只能是 4~8 之间。

三、页目录查找记录的过程

现在继续向测试表里插入 12 条数据,也就是说在页中共有 18 条记录。

然后这些记录就被分成了 5 个组,这里参考书籍上的示意图(只保留一些关键属性):

现在,要查找主键是 6 的记录,要如何进行?

因为 5 个槽的编号分别为 0、1、2、3、4 挨着的,并且里面的主键值也都是从小到大进行排序的,可以使用二分法(不清楚的可以百度),那么初始情况下 low=0,high=4:

  1. 计算中间槽的位置,(0+4)/ 2=2,于是查看槽 2 对应记录的主键值为 8,因为 8 > 6,所以 high = 2,low 不变。
  2. 重新计算中间槽位置,(0+2)/ 2=1,于是查看槽 1 对应记录的主键为4,因为 4 < 6,所以 high 不变,low = 1。
  3. 因为 high - low = 1,所以确定主键值为6 的记录就在槽 2 对应的组中。接着找到该组中主键最小的记录,沿着单链表向后遍历,最终找到主键 6 的记录。

这里有个问题,槽对应的值都是这个组的主键最大的记录,如何找到组里最小的记录?比如槽 2 对应最大主键是 8 的记录,那如何找到最小记录。

解决办法是:

  • 通过槽 2 找到 槽 1 对应的记录,也就是主键为 4 的记录。
  • 主键为 4 的记录的下一条记录就是槽 2 当中主键最小的记录,可以找到主键 5。

总结

在一个数据页中查找指定主键值的记录,过程分为 2 步:

  1. 通过二分法确定该记录所在分组对应的槽,然后找到该槽所在分组中主键值最小的记录。
  2. 通过记录的 next_record 属性比那里该槽所在组的各个记录,最终找到目标记录。

本文参考书籍:
小孩子4919 《mysql是怎样运行的》

【Mysql】InnoDB 引擎中的页目录的更多相关文章

  1. 聊一聊 InnoDB 引擎中的索引类型

    索引对数据库有多重要,我想大家都已经知道了吧,关于索引可能大家会对它多少有一些误解,首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书 ...

  2. InnoDB 引擎中的索引类型

    首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书本的目录一样,能否快速的查找到你需要的信息,取决于你设计的目录是否合理. MySQL ...

  3. 巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

    该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深 ...

  4. Innodb引擎中Count(*)

    select count(*)是MySQL中用于统计记录行数最常用的方法,count方法可以返回表内精确的行数. 在某些索引下是好事,但是如果表中有主键,count(*)的速度就会很慢,特别在千万记录 ...

  5. Mysql InnoDB引擎下 事务的隔离级别

    mysql InnoDB 引擎下事物学习 建表user CREATE TABLE `user` ( `uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, ...

  6. 聊一聊 InnoDB 引擎中的这些索引策略

    在上一篇中,我们简单的介绍了一下 InnoDB 引擎的索引类型,这一篇我们继续学习 InnoDB 的索引,聊一聊索引策略,更好的利用好索引,提升数据库的性能,主要聊一聊覆盖索引.最左前缀原则.索引下推 ...

  7. 为什么 select count(*) from t,在 InnoDB 引擎中比 MyISAM 慢?

    统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from t SQL 语句来完成.随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什 ...

  8. 【Mysql】InnoDB 引擎中的数据页结构

    InnoDB 是 mysql 的默认引擎,也是我们最常用的,所以基于 InnoDB,学习页结构.而学习页结构,是为了更好的学习索引. 一.页的简介 页是 InnoDB 管理存储空间的基本单位,一个页的 ...

  9. MySQL存储引擎中的MyISAM和InnoDB区别详解

    在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...

随机推荐

  1. https ssl(tls)为什么不直接用公钥加密数据?

    很多人都提到了非对称加密速度慢,但这只是一个原因,但不是主要原因,甚至是微不足道的原因. SSL协议到3.0后就已经到头了,取而代之的是TLS,相较于SSL的"安全套接字层"的命名 ...

  2. XML文件存在中文注释报错问题( 3 字节的 UTF-8 序列的字节 3 无效)

    今天在做mybatis项目的时候,给映射文件添加了中文注释后,程序就报错.把中文注释删除后,程序又可以正常执行.解决方法在下文提到. 我的xml映射文件如下: <?xml version=&qu ...

  3. centos 7 增加一块硬盘的步骤

    1) 增加一块硬盘 1G [到设置中添加一块硬盘即可] 2) 重启一下服务器 lsblk -f 查看硬盘 3) 给 sdb 硬盘分区 fdisk /dev/sdb n,p,enter,enter,w ...

  4. Spring Boot WebFlux-02——WebFlux Web CRUD 实践

    第02课:WebFlux Web CRUD 实践 上一篇基于功能性端点去创建一个简单服务,实现了 Hello.这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD We ...

  5. Centos8.3、mysql8.0主从复制实战记录

    引言 最近又上线了一个项目,感觉自己这段时间收获不少就想把自己做这个项目用的技术总结梳理一下.这个项目是我自己发起,领导们不是特别重视所以得到资源有限,资源有限的情况我只能选择手动搭建数据库环境,资源 ...

  6. 【模拟7.29】大佬(概率期望DP)

    首先根据数据范围,可以判断基本上是n^2的复杂度 通过分析我们发现每一次都可以从m个数中任意选,既然任意选,那么此时的概率的分母就是不变的,然而题中涉及的是某一段的最大值,所以我们按套路假设 f[i] ...

  7. IDEA2020.2版本设置类和方法的自定义注释模板

    IDEA是目前普遍使用的Java开发编辑器,添加自定义的注释模板,一方面便捷好用,另外一方面可以规范开发.IDEA中设置模板分两种:1.创建Java类的注释,2.方法的注释. 一.Java类的注释模板 ...

  8. Hive和Spark分区策略

    1.概述 离线数据处理生态系统包含许多关键任务,最大限度的提高数据管道基础设施的稳定性和效率是至关重要的.这边博客将分享Hive和Spark分区的各种策略,以最大限度的提高数据工程生态系统的稳定性和效 ...

  9. 数据同步Datax与Datax_web的部署以及使用说明

    一.DataX3.0概述 DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.ODPS.HBase.FTP等各种异构数据源之间稳定高 ...

  10. Java常见面试题 非常实用【个人经验】

    必收藏的Java面试题 目录 Java 面试题 一.容器部分 二.多线程部分 三.SpringMvc部分 四.Mybatis部分 五.MySQL部分 六.Redis部分 七.RabbitMQ部分 八. ...