Mysql 默认使用 InnoDb 引擎,数据是页为单位进行操作的(以页为单位从磁盘读入数据,同样以页为单位将内存中的数据写入磁盘),默认大小为 16kB。

数据页分为 7 个部分

名称 描述
文件头
页头 数据页的状态信息
最小,最大记录 伪记录,主要用于查找
用户记录 存储记录内容
空闲空间
页目录 见下文
文件尾 校验数据,通过这个数据校验读取的数据页是否正确

数据页以链表的形式存储,即在文件头中有两个指针,指向上一个和下一个数据页,类似于双向链表的结构。

页目录

数据页中的记录按照主键顺序组成单向链表,单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索。因此,数据页中有一个页目录,起到记录的索引作用。

数据库中的记录在用户记录的部分,记录被分为几个组(包括最大,最小记录),一个数据页上的所有记录组成一个单向链表,单项链表的最后一个元素上保存了链表中元素的数量。

每一个记录组的记录数量有限制:

  • 第一个分组只能有一条记录
  • 最后一个分组有 1~8 条数据
  • 其余分组有 4~8 条记录

页目录分为多个槽,每个槽于记录的一个组相对应,每个槽中储存每组最后一条记录的偏移地址。

这种结构类似于 redis 中的跳表,将链表层级化(这里只有两层,而跳表中有多层)。