外观
MySQL 一行记录是怎么存储的
在 MySQL
中,一行记录的存储涉及多个层面,包括存储引擎层面、页结构以及记录在页内的组织方式等。
1.存储引擎层面
MySQL
支持多种存储引擎,不同的存储引擎对于一行记录的存储方式有所不同,其中 InnoDB
是最常用的存储引擎,以下以 InnoDB
为例进行说明。
InnoDB
采用面向页的存储方式,数据被组织成页(Page
)的形式进行存储,页是 InnoDB
磁盘 I/O
的基本单位,默认大小为 16KB
。表中的数据会被划分到多个页中,每行记录存储在页内。
2.页结构
InnoDB
的页有多种类型,用于存储数据的页主要是索引页(Index Page
),也称为数据页。一个典型的数据页包含以下几个部分:
- 文件头(
File Header
):包含页的一些通用信息,如页的校验和、上一个页和下一个页的编号等,用于管理页之间的顺序和完整性。 - 页头(
Page Header
):记录页的状态信息,如页中记录的数量、第一个记录的位置等。 - 最大最小记录(
Infimum
+Supremum Records
):这是两个虚拟记录,分别表示页内记录的最小和最大边界。 - 用户记录(
User Records
):实际存储用户插入的数据记录。 - 空闲空间(
Free Space
):尚未被使用的空间,用于后续插入新记录。 - 页目录(
Page Directory
):存储记录的目录信息,用于快速定位记录。 - 文件尾(
File Trailer
):用于验证页的完整性,包含与文件头中校验和相同的值。
3.记录在页内的组织方式
记录格式
InnoDB
有两种主要的记录格式:Compact
格式和 Redundant
格式,这里主要介绍 Compact
格式。 一个 Compact
格式的记录主要由以下几部分组成:
- 记录头信息(
Record Header
):包含记录的一些元数据,如记录的删除标记、记录的长度、下一条记录的相对位置等。 - 变长字段长度列表(
Variable Length Fields Length List
):如果记录中包含变长字段(如VARCHAR
、TEXT
等),该列表会记录每个变长字段的实际长度。 NULL
值列表(NULL Flags
):用于标记记录中哪些字段的值为NULL
。- 列数据(
Column Data
):实际存储的列值。
记录的物理存储
在页内,记录按照插入的顺序依次存储,并且通过记录头信息中的指针形成一个单向链表。新插入的记录会被添加到链表的末尾。
当插入新记录时,如果页内的空闲空间足够,记录会直接插入到空闲空间中;如果空闲空间不足,InnoDB
会进行页分裂操作,创建一个新的页,并将部分记录移动到新页中。
示例:
-- 创建一个简单的表
CREATE TABLE test_table (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT
);
-- 插入一行记录
INSERT INTO test_table (id, name, age) VALUES (1, 'John', 25);
在执行上述 SQL
语句后,插入的这一行记录会按照前面介绍的方式存储在 InnoDB
的数据页中。 综上所述,MySQL
中一行记录在 InnoDB
存储引擎下,首先被组织到数据页中,页内的记录按照 Compact
或 Redundant
等格式进行存储,并通过指针形成链表结构。