纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

MySQL 页原理 浅谈MySQL之浅入深出页原理

detectiveHLH   2021-06-23 我要评论
想了解浅谈MySQL之浅入深出页原理的相关内容吗detectiveHLH在本文为您仔细讲解MySQL 页原理的相关知识和一些Code实例欢迎阅读和指正我们先划重点:MySQL,页原理下面大家一起来学习吧

一、页的概览

我们往 MySQL 插入的数据最终都是存在页中的在 InnoDB 中的设计中页与页之间是通过一个双向链表连接起来

而存储在页中的一行一行的数据则是通过单链表连接起来的

上图中的 User Records 的区域就是用来存储行数据的那 InnoDB 为什么要这么设计?假设我们没有页这个概念那么当我们查询时成千上万的数据要如何做到快速的查询出结果?众所周知MySQL 的性能是不错的而如果没有页我们剩下的只能是逐条逐条的遍历数据了

那页是如何做到快速查询的呢?在当前页中可以通过 User Records 中的连接每条记录的单链表来进行遍历如果在当前页中没有找到则可以通过下一页指针快速的跳到下一页进行查询

二、Infimum 和 Supremum

有人可能会说了你在 User Records 中还不是通过遍历来解决的你就是简单的把数据分了个组而已如果我的数据根本不在当前这个页中那我难道还是得把之前的页中的每一条数据全部遍历完?这效率也太低了

当然MySQL 也考虑到了这个问题所以实际上在页中还存在一块区域叫做 The Infimum and Supremum Records 代表了当前页中最大和最小的记录

有了 Infimum RecordSupremum Record 现在查询不需要将某一页的 User Records 全部遍历完只需要将这两个记录和待查询的目标记录进行比较比如我要查询的数据 id = 101 那很明显不在当前页接下来就可以通过下一页指针跳到下页进行检索

三、使用Page Directory

可能有人又会说了你这 User Records 里不也全是单链表吗?即使我知道我要找的数据在当前页那最坏的情况下不还是得挨个挨个的遍历100次才能找到我要找的数据?你管这也叫效率高?

不得不说这的确是个问题不过是一个 MySQL 已经考虑到的问题不错挨个遍历确实效率很低为了解决这个问题MySQL 又在页中加入了另一个区域 Page Directory 

顾名思义Page Directory 是个目录里面有很多个槽位(Slots)每一个槽位都指向了一条 User Records 中的记录大家可以看到每隔几条数据就会创建一个槽位其实我图中给出的数据是非常严格按照其设定来的在一个完整的页中每隔6条数据就会有一个 Slot

Page Directory 的设计不知道有没有让你想起另一个数据结构——跳表只不过这里只抽象了一层索引

MySQL 会在新增数据的时候就将对应的 Slot 创建好有了 Page Directory 就可以对一张页的数据进行粗略的二分查找至于为什么是粗略毕竟 Page Directory 中不是完整的数据二分查找出来的结果只能是个大概的位置找到了这个大概的位置之后还需要回到 User Records 中继续的进行挨个遍历匹配

不过这样的效率已经比我们刚开始聊的原始版本高了很多了

四、页的真实面貌

如果我开篇就把页的各种组成部分各种概念直接抛出来首先我自己接受不了这样显得很僵硬其次对页不熟悉的人应该是不太能理解页为什么要这么设计的所以我按照查询一条数据的一套思路把页的大致的面貌呈现给了大家

实际上页上还存储了很多其他的字段也还有其他的区域但是这些都不会影响到我们对页的理解所以在对页有了一个较为清晰的认知之后我们就可以来看看真实的页到底长啥样了

上图就是页的实际全部组成除了我们之前提到过的还多了一些之前没有聊过的例如 File HeaderPage HeaderFree SpaceFile Tailer 我们一个一个来看

4.1、File Header

其实File Header 在上文已经聊过了只是不叫这个名字上面提到的上一页指针和下一页指针其实就是属于File Header的除此之外还有很多其他的数据

其实我比较抗拒把一堆参数列出来告诉你这个大小多少那个用来干嘛对于我们需要详细了解页来说其实暂时只需要知道两个就足够了分别是:

  • FIL_PAGE_PREV
  • FIL_PAGE_NEXT

这两个变量就是上文提到过的上一页指针和下一页指针说是指针是为了方便大家理解实际上是页在磁盘上的偏移量

4.2、Page Header

比起 File Header Page Header 中的数据对我们来说就显得更加熟悉了我这里画了一张图把里面的内容详细的列了出来

这里全列出来是因为了解这些参数的含义和为什么要设置参数能够更好的帮助我们了解页的原理和构造具体的看图说话就行

这里也很想吐槽太多博客都写的太僵硬比如参数 PAGE_HEAP_TOP 这里的 HEAP 很多博客都直接叫堆这就跟你给Init写注释叫初始化一样还不如不写实际上你去研究一下就会知道这里的堆实际上就是指User Records

里面有个两个参数可能会有点混淆分别是PAGE_N_HEAPPAGE_N_RECS 都是当前 User Records 中记录的数量唯一的不同在于PAGE_N_HEAP 中是包含了被标记为删除的记录的 而 PAGE_N_RECS 中就是实际上我们能够查询到的所有数据

4.3、Infimum & Supremum Records

上文中提到Infimum & Supremum Records会记录当前页最大最小记录实际上不准确更准确的描述是最小记录和最大纪录的开区间因为实际上 Infimum Records 会比当前页中的最小值还要小而 Supremum Records 会比当前页中的最大值要大

4.4、User Records

User Records 可以说是我们平时接触的最多的部分了毕竟我们的数据最终都在这页被初始化之后User Records 中是没有数据的随着系统运行数据产生User Records 中的数据会不断的膨胀相应的 Free Space 空间会慢慢的变小

关于 User Records 中的概念之前已经聊过了这里只聊我认为很关键的一点那就是顺序

我们知道在聚簇索引中Key 实际上会按照 Primary Key 的顺序来进行排列那在 User Records 中也会这样吗?我们插入一条新的数据到 User Records 中时是否也会按照 Primary Key 的顺序来对已有的数据重排序?

答案是不会因为这样会拉低 MySQL 处理的效率

User Records 中的数据是由单链表指针的指向来保证的也就是说行数据实际在磁盘上的表现是按照插入顺序来排队的先到的数据在前面后来的数据在后面只不过通过 User Records 中的行数据之间的单链表形成了一个按照 Primary Key排列的顺序

用图来表示大概如下:

4.5、Free Space

这块其实变相的在其他的模块中讨论了最初 User Records 是完全空的当有新数据进来时会来 Free Space 中申请空间当 Free Space 没空间了则说明需要申请新的页了其他没什么特别之处

4.6、Page Directory

这跟上文讨论的没什么出入就直接跳过了

4.7、File Trailer

这块主要是为了防止页在刷入磁盘的过程中由于极端的意外情况(网络问题、火灾、自然灾害)导致失败而造成数据不一致的情况也就是说形成了脏页

里面有只有一个组成部分:

五、总结

到此我认为关于页的所有东西就聊的差不多了了解了底层的页原理我个人认为是有助于我们更加友好、理智的使用 MySQL 的使其能发挥出自己应该发挥的极致性能


相关文章

猜您喜欢

  • Qt连接OpenGauss数据库 通过Qt连接OpenGauss数据库的详细教程

    想了解通过Qt连接OpenGauss数据库的详细教程的相关内容吗一 学在本文为您仔细讲解Qt连接OpenGauss数据库的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Qt连接OpenGauss数据库,Qt,OpenGauss数据库下面大家一起来学习吧..
  • Unity3D快速入门 Unity3D快速入门教程

    想了解Unity3D快速入门教程的相关内容吗kybshj在本文为您仔细讲解Unity3D快速入门的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Unity3D入门,Unity3D快速入门,Unity3D入门教程下面大家一起来学习吧..

网友评论

Copyright 2020 www.gamerfx.net 【游戏天空】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式