一文理解MySQL中的page页
怎么入门数据库编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《一文理解MySQL中的page页》,涉及到MySQL,有需要的可以收藏一下
最新版本请查看原文:https://blog.haohtml.com/arch...
在介绍InnoDB中的页的时候,很有必要先让大家了解一下InnoDB中的存储结构

从InnoDB存储引擎的逻辑结构看,所有数据都被逻辑地存放在一个空间内,称为表空间(tablespace),而表空间由段(sengment)、区(extent)、页(page)组成。 在一些文档中extend又称块(block)。
一、表空间(table space)
表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间等。
在 InnoDB 中存在两种表空间的类型:共享表空间和独立表空间。如果是共享表空间就意味着多张表共用一个表空间。如果是独立表空间,就意味着每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间可以在不同的数据库之间进行迁移。可通过命令
mysql > show variables like 'innodb_file_per_table';
查看当前系统启用的表空间类型。目前最新版本已经默认启用独立表空间。
InnoDB把数据保存在表空间内,表空间可以看作是InnoDB存储引擎逻辑结构的最高层。本质上是一个由一个或多个磁盘文件组成的虚拟文件系统。InnoDB用表空间并不只是存储表和索引,还保存了回滚段、双写缓冲区等。
二、段(segment)
段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在 InnoDB 中是连续的 64 个页),不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会相应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。
三、区(extent)
在 InnoDB 存储引擎中,一个区会分配 64 个连续的页。因为 InnoDB 中的页大小默认是 16KB,所以一个区的大小是 64*16KB=1MB。在任何情况下每个区大小都为1MB,为了保证页的连续性,InnoDB存储引擎每次从磁盘一次申请4-5个区。默认情况下,InnoDB存储引擎的页大小为16KB,即一个区中有64个连续的页。
四、页(Page)
页是InnoDB存储引擎磁盘管理的最小单位,每个页默认16KB;InnoDB存储引擎从1.2.x版本碍事,可以通过参数innodb_page_size将页的大小设置为4K、8K、16K。若设置完成,则所有表中页的大小都为innodb_page_size,不可以再次对其进行修改,除非通过mysqldump导入和导出操作来产生新的库。
innoDB存储引擎中,常见的页类型有:
1. 数据页(B-tree Node)
2. undo页(undo Log Page)
3. 系统页 (System Page)
4. 事物数据页 (Transaction System Page)
5. 插入缓冲位图页(Insert Buffer Bitmap)
6. 插入缓冲空闲列表页(Insert Buffer Free List)
7. 未压缩的二进制大对象页(Uncompressed BLOB Page)
8. 压缩的二进制大对象页 (compressed BLOB Page)
五、行(row)
InnoDB存储引擎是按行进行存放的,每个页存放的行记录也是有硬性定义的,最多允许存放16KB/2-200,即7992行记录。
了解了整体架构,下面我们开始详细对Page来做一些介绍。
先贴一张Page完整的结构图

上较的概念实在太多了,为了方便理解,可以按下面的分解一下Page的结构

每部分的意义


页结构整体上可以分为三大部分,分别为通用部分(文件头、文件尾)、存储记录空间、索引部分。
第一部分通用部分,主要指文件头和文件尾,将页的内容进行封装,通过文件头和文件尾校验的CheckSum方式来确保页的传输是完整的。
在文件头中有两个字段,分别是 FIL_PAGE_PREV 和 FIL_PAGE_NEXT,它们的作用相当于指针,分别指向上一个数据页和下一个数据页。连接起来的页相当于一个双向的链表,如下图所示:

需要说明的是采用链表的结构让数据页之间不需要是物理上的连续,而是逻辑上的连续。
第二个部分是记录部分,页的主要作用是存储记录,所以“最小和最大记录”和“用户记录”部分占了页结构的主要空间。另外空闲空间是个灵活的部分,当有新的记录插入时,会从空闲空间中进行分配用于存储新记录,如下图所示:

一个页内必须存储2行记录,否则就不是B+tree,而是链表了。
第三部分是索引部分,这部分重点指的是页目录(示意图2中的s0-sn),它起到了记录的索引作用,因为在页中,记录是以单向链表的形式进行存储的。单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索,因此在页目录中提供了二分查找的方式,用来提高记录的检索效率。这个过程就好比是给记录创建了一个目录:
将所有的记录分成几个组,这些记录包括最小记录和最大记录,但不包括标记为“已删除”的记录。
第 1 组,也就是最小记录所在的分组只有 1 个记录;
最后一组,就是最大记录所在的分组,会有 1-8 条记录;
其余的组记录数量在 4-8 条之间。
这样做的好处是,除了第 1 组(最小记录所在组)以外,其余组的记录数会尽量平分。
在每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned 字段。
页目录用来存储每组最后一条记录的地址偏移量,这些地址偏移量会按照先后顺序存储起来,每组的地址偏移量也被称之为槽(slot),每个槽相当于指针指向了不同组的最后一个记录。如下图所示:

页目录存储的是槽,槽相当于分组记录的索引。我们通过槽查找记录,实际上就是在做二分查找。这里我以上面的图示进行举例,5 个槽的编号分别为 0,1,2,3,4,我想查找主键为 9 的用户记录,我们初始化查找的槽的下限编号,设置为 low=0,然后设置查找的槽的上限编号 high=4,然后采用二分查找法进行查找。
首先找到槽的中间位置 p=(low+high)/2=(0+4)/2=2,这时我们取编号为 2 的槽对应的分组记录中最大的记录,取出关键字为 8。因为 9 大于 8,所以应该会在槽编号为 (p,high] 的范围进行查找
接着重新计算中间位置 p’=(p+high)/2=(2+4)/2=3,我们查找编号为 3 的槽对应的分组记录中最大的记录,取出关键字为 12。因为 9 小于 12,所以应该在槽 3 中进行查找。
遍历槽 3 中的所有记录,找到关键字为 9 的记录,取出该条记录的信息即为我们想要查找的内容。
B+ 树是如何进行记录检索的?
如果通过 B+ 树的索引查询行记录,首先是从 B+ 树的根开始,逐层检索,直到找到叶子节点,也就是找到对应的数据页为止,将数据页加载到内存中,页目录中的槽(slot)采用二分查找的方式先找到一个粗略的记录分组,然后再在分组中通过链表遍历的方式查找记录。
好了,本文到此结束,带大家了解了《一文理解MySQL中的page页》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多数据库知识!

- 上一篇
- 数据库问答集萃第三期 - 墨天轮2021

- 下一篇
- 数据库周刊65丨TiDB 5.0 GA版发布;Oracle日志切换频繁问题;MySQL连表查询优化案例;PG SQL开发规范……
-
- 善良的山水
- 细节满满,码起来,感谢老哥的这篇博文,我会继续支持!
- 2023-03-26 12:16:13
-
- 要减肥的唇膏
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢老哥分享文章内容!
- 2023-03-08 15:10:59
-
- 老迟到的自行车
- 这篇文章真及时,太全面了,受益颇多,已加入收藏夹了,关注作者大大了!希望作者大大能多写数据库相关的文章。
- 2023-03-03 06:19:58
-
- 曾经的项链
- 这篇技术贴出现的刚刚好,很详细,受益颇多,mark,关注作者大大了!希望作者大大能多写数据库相关的文章。
- 2023-03-02 23:54:00
-
- 优美的猎豹
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者分享文章内容!
- 2023-02-17 18:02:22
-
- 腼腆的芹菜
- 这篇文章出现的刚刚好,作者加油!
- 2023-02-14 11:55:27
-
- 天真的小鸭子
- 这篇技术文章真及时,好细啊,很有用,mark,关注楼主了!希望楼主能多写数据库相关的文章。
- 2023-02-12 16:25:14
-
- 舒服的春天
- 好细啊,mark,感谢up主的这篇文章,我会继续支持!
- 2023-02-12 04:26:42
-
- 苹果刺猬
- 很好,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者大大分享文章!
- 2023-02-12 02:24:43
-
- 数据库 · MySQL | 1小时前 | jdbc 性能优化 连接池 MySQLConnector/Python mysql2
- MySQL数据库连接技巧与常见问题攻略
- 466浏览 收藏
-
- 数据库 · MySQL | 3小时前 |
- 解析MySQL数据库特性与优势,深入浅出
- 228浏览 收藏
-
- 数据库 · MySQL | 3小时前 | 表结构 索引优化 降序排序 DESC SHOWCREATETABLE
- MySQL中desc用法:降序排序及表结构查看
- 268浏览 收藏
-
- 数据库 · MySQL | 5小时前 |
- MySQL数据库深度解析:特性与优势详解
- 200浏览 收藏
-
- 数据库 · MySQL | 5小时前 | 备份 DROPTABLE TRUNCATETABLE IFEXISTS 外键检查
- MySQL详解droptable命令及表结构删除
- 207浏览 收藏
-
- 数据库 · MySQL | 5小时前 | Python脚本 mysql--version sudosystemctlstatusmysql
- MySQL安装验证三种快速方法
- 143浏览 收藏
-
- 数据库 · MySQL | 5小时前 |
- MySQL建表示例:全约束详解
- 262浏览 收藏
-
- 数据库 · MySQL | 22小时前 | Python 环境变量 systemd mysql--version sudosystemctlstatusmysql
- MySQL快速检测方法:三种技巧
- 454浏览 收藏
-
- 数据库 · MySQL | 1天前 | mysql 数据库管理 性能优化 use CREATEDATABASE
- MySQL创建数据库后如何进入?用use命令切换
- 388浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 魔匠AI
- SEO摘要魔匠AI专注于高质量AI学术写作,已稳定运行6年。提供无限改稿、选题优化、大纲生成、多语言支持、真实参考文献、数据图表生成、查重降重等全流程服务,确保论文质量与隐私安全。适用于专科、本科、硕士学生及研究者,满足多语言学术需求。
- 10次使用
-
- PPTFake答辩PPT生成器
- PPTFake答辩PPT生成器,专为答辩准备设计,极致高效生成PPT与自述稿。智能解析内容,提供多样模板,数据可视化,贴心配套服务,灵活自主编辑,降低制作门槛,适用于各类答辩场景。
- 26次使用
-
- Lovart
- SEO摘要探索Lovart AI,这款专注于设计领域的AI智能体,通过多模态模型集成和智能任务拆解,实现全链路设计自动化。无论是品牌全案设计、广告与视频制作,还是文创内容创作,Lovart AI都能满足您的需求,提升设计效率,降低成本。
- 25次使用
-
- 美图AI抠图
- 美图AI抠图,依托CVPR 2024竞赛亚军技术,提供顶尖的图像处理解决方案。适用于证件照、商品、毛发等多场景,支持批量处理,3秒出图,零PS基础也能轻松操作,满足个人与商业需求。
- 35次使用
-
- PetGPT
- SEO摘要PetGPT 是一款基于 Python 和 PyQt 开发的智能桌面宠物程序,集成了 OpenAI 的 GPT 模型,提供上下文感知对话和主动聊天功能。用户可高度自定义宠物的外观和行为,支持插件热更新和二次开发。适用于需要陪伴和效率辅助的办公族、学生及 AI 技术爱好者。
- 36次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览