MySQL 页结构与数据存储原理全解析》

365bet线上足球 admin 2026-07-11 11:59:28

文章目录

[《MySQL 页结构与数据存储原理全解析》](#《MySQL 页结构与数据存储原理全解析》)

[一、前言:理解页结构,是深入 InnoDB 的起点](#一、前言:理解页结构,是深入 InnoDB 的起点)

二、页的定义与基本单位

三、页的内部结构详解

[(1)File Header(文件头)](#(1)File Header(文件头))

[(2)Page Header(页头)](#(2)Page Header(页头))

[(3)Infimum/Supremum Record](#(3)Infimum/Supremum Record)

[(4)User Records(用户记录)](#(4)User Records(用户记录))

[(5)Free Space(空闲空间)](#(5)Free Space(空闲空间))

[(6)Page Directory(页目录)](#(6)Page Directory(页目录))

四、数据行在页中的存储方式

举例说明

五、索引页与数据页的关系

六、页分裂与合并

七、面试高频问题与答题模板

[八、总结:理解页,就是理解 InnoDB](#八、总结:理解页,就是理解 InnoDB)

《MySQL 页结构与数据存储原理全解析》

一、前言:理解页结构,是深入 InnoDB 的起点

大家好,我是程序员卷卷。

我们平时写 SQL 时,看到的都是逻辑上的"表""行""列",

但在 InnoDB 的底层,这一切都以 页(Page) 为单位进行物理存储与管理。

无论是索引查找、缓冲缓存、磁盘读写,最小单位都是"页"。

这意味着:

如果你真正理解了页的结构,就能从底层解释"为什么随机 IO 慢、为什么自增主键快、为什么行锁粒度能控制到单行"。

二、页的定义与基本单位

在 InnoDB 中:

页(Page)是磁盘与内存交互的最小单位;

每页默认大小为 16KB;

多个页组成区(Extent,1MB),多个区组成段(Segment),段组成表空间(Tablespace)。

层级结构如下:

复制代码

表空间(Tablespace)

├── 段(Segment)

│ └── 区(Extent)

│ └── 页(Page, 16KB)

│ └── 行(Row)

简单理解:

InnoDB 把磁盘空间分成了一个个"16KB 的小格子",每个格子就是一个 Page。

三、页的内部结构详解

每个页内部都包含固定的逻辑结构,可分为以下部分

复制代码

┌───────────────────────────┐

│ File Header(文件头) │ 38字节,存页号、校验值等

│ Page Header(页头) │ 56字节,页目录、行数等

│ Infimum/Supremum Record │ 固定两条虚拟记录

│ User Records(用户记录) │ 存储真实数据行

│ Free Space(空闲空间) │ 插入新行时使用

│ Page Directory(页目录) │ 记录偏移地址,加快查找

│ File Trailer(校验信息) │ 校验页完整性

└───────────────────────────┘

(1)File Header(文件头)

记录页的编号、上一个页、下一个页、校验值,用于维护 B+Tree 的双向链表结构。

(2)Page Header(页头)

存储当前页中记录数量、最小和最大记录位置等元信息。

(3)Infimum/Supremum Record

两条虚拟记录,分别代表"最小值"和"最大值",

保证页内记录有序,便于二分查找。

(4)User Records(用户记录)

实际存储表中的数据行。

InnoDB 会根据主键顺序在页内排序,形成 B+Tree 的叶子节点结构。

(5)Free Space(空闲空间)

用于存放后续新增的行,当空间不足时会触发页分裂。

(6)Page Directory(页目录)

存储每条记录的偏移地址,用于加速定位。

查找记录时,InnoDB 先通过目录定位,再顺序扫描。

四、数据行在页中的存储方式

每一行数据在页中以"记录(Record)"形式存在,

每条记录包含两部分:记录头信息 + 实际列值。

复制代码

┌───────────────────────────────┐

│ Record Header(记录头,5字节)│

│ + delete_flag │

│ + next_record 指针 │

│ + record_type │

│ Column Values(真实列数据) │

└───────────────────────────────┘

举例说明

表结构:

sql

复制代码

CREATE TABLE user (

id INT PRIMARY KEY,

name VARCHAR(20),

age INT

) ENGINE=InnoDB;

在页中表现为:

页内记录根据 主键 id 有序排列;

每条记录包含一个 "next_record" 指针,形成单向链表;

通过页目录(Page Directory)加速二分查找;

若页满,页会分裂(Page Split),形成新的页并更新 B+Tree 链接。

五、索引页与数据页的关系

InnoDB 的 B+Tree 索引中:

叶子节点页 存放实际数据行(称为"数据页");

非叶子节点页 存放索引键与指针(称为"索引页")。

示意图如下

复制代码

┌─────────────────────┐

│ 根节点页 │

└─────────┬───────────┘

┌─────────┴───────────┐

┌────────▼────────┐ ┌────────▼────────┐

│ 索引页(中间层) │ │ 索引页(中间层) │

└────────┬────────┘ └────────┬────────┘

┌───────▼───────┐ ┌───────▼───────┐

│ 数据页(叶子层) │ │ 数据页(叶子层) │

└────────────────┘ └────────────────┘

所以 InnoDB 的主键索引即"聚簇索引",

数据行就存放在 B+Tree 的叶子节点中。

六、页分裂与合并

当插入新数据导致页满时:

InnoDB 会分裂出新页;

重新分配部分记录;

更新父节点指针。

页合并发生在删除大量数据时,

若相邻页利用率过低,会自动合并,减少碎片。

这两种操作是维护 B+Tree 平衡结构的关键。

七、面试高频问题与答题模板

问题

答案要点

Q1:InnoDB 一页多大?为什么是 16KB?

默认 16KB,兼顾 I/O 性能与内存命中率。

Q2:为什么 InnoDB 查找时要"回表"?

因为二级索引页存储主键值,需要到数据页(聚簇索引)获取完整行数据。

Q3:页目录的作用是什么?

存储记录偏移,加快页内定位。

Q4:页分裂是什么?

页空间不足时,数据部分迁移到新页,更新索引指针。

Q5:InnoDB 的叶子页与非叶子页区别?

叶子页存数据行,非叶子页存索引键与页号指针。

Q6:页是如何在内存与磁盘之间交互的?

InnoDB Buffer Pool 以页为单位进行读写与缓存。

八、总结:理解页,就是理解 InnoDB

MySQL 的性能优化,本质上就是对"页"的利用优化。

索引查找靠页定位;

Buffer Pool 按页缓存;

磁盘 I/O 按页读写;

表结构设计决定页利用率。

理解页结构,就能从物理层回答:

"为什么自增主键比随机主键更快?"

------因为自增主键插入不会频繁触发页分裂。

下一篇(第 4 篇),我将写------

《CHAR、VARCHAR、TEXT 的差别与存储方式》 ,

带你理解字符串类型的底层存储差异、长度限制与性能影响。

相关文章

自制酸奶就是牛奶加菌粉然后等?怪不得你做出来的不浓稠不顺滑

中国校服为什么这么“丑”?漫画揭晓:我国校服的发展史

快手怎么查看快手币数量 快手查看快手币数量方法【详解】

德阳彩虹桥,为什么没有了彩虹?

详细教程设置

焦点丨价格刺客、乱停乱放……共享单车乱象何解?

WPS投影宝怎么使用?具体操作流程介绍

创客中国

形容鱼和猫的成语大全