一、数据库的存储结构:页
索引与存储:索引结构提供高效索引方式,索引信息和数据记录保存在文件的页结构中
存储引擎职责:索引在存储引擎中实现,MySQL 的存储引擎负责表中数据的读写,不同存储引擎数据存放格式一般不同,如 Memory 引擎不用磁盘存储数据
(1)磁盘与内存交互基本单位:页
- 页的大小:InnoDB 将数据划分为页,页大小默认 16KB
- 交互单位:页是磁盘与内存交互的基本单位,一次至少从磁盘读 16KB 内容到内存,或把内存中 16KB 内容刷新到磁盘
- 读取方式:数据库读数据时,不论一行或多行,都加载行所在的页,页是数据库管理存储空间和 I/O 操作的基本单位,一个页可存多个行记录
- 效率考量:记录按行存储,但不以行为读取单位,否则一次 I/O 仅处理一行数据,效率极低
- 图示:
(2)页结构概述
InnoDB 中,页与页之间无需在物理结构上相连,通过双向链表关联即可。每个数据页内的记录按主键值从小到大组成单向链表,同时每个数据页会为其中的记录生成页目录。当通过主键查找记录时,可利用页目录进行二分法快速定位到对应的槽,再遍历该槽对应分组里的记录,从而迅速找到目标记录
(3)页的大小
- 不同的DBMS的页大小不同。比如在MySQL的InnoDB存储引擎中,默认页的大小是16KB,我们可以通过下面的命令来进行查看:
- SQL Server中页的大小为8KB,而在Oracle中我们用术语“块”(Block)来代表“页”,Oracle支持的块大小为2KB,4KB,8KB,16KB,32KB和64KB
(4)页的上层结构
- 另外在数据库中,还存在着区(Extent)、段(Segment)和表空间(TableSpace)的概念。行、页、区、段、表空间的关系如下图所示:
- 区(Extent):是比页高一级的存储结构,InnoDB 里一个区含 64 个连续的页。因页默认 16KB,所以一个区大小为 1MB
- 段(Segment):由一个或多个区组成,区在文件系统中是连续存储空间(InnoDB 中为连续 64 个页),但段内区与区不要求相邻。段是数据库分配单位,不同数据库对象以不同段形式存在,创建表和索引时会分别创建表段和索引段
- 表空间(TableSpace):是逻辑容器,存储对象为段。一个表空间可有一个或多个段,一个段仅属一个表空间。数据库由一个或多个表空间组成,表空间管理上分为系统、用户、撤销、临时表空间等
二、页的内部结构
数据页的16KB大小的存储空间被划分为七个部分,分别是文件头部(File Header)、页面头部(Page Header)、最大最小记录(Infimum+supremum)、用户记录(User Records)、空闲空间(Free Space)、页目录(Page Directory)、文件尾部(File Trailer)
页结构的示意图如下所示:
这七个部分的作用分别如下,我们简单梳理如下表所示:
(1)第1部分:File Header(文件头部)和File Trailer(文件尾部)
2.1.1File Header(文件头部)(38字节)
- 作用:描述各种页的通用信息(比如页的编号、其上一页、下一页是谁)
- 大小:38字节
- 构成:
- FIL_PAGE_OFFSET:InnoDB 中每个页都有唯一的页号,通过页号能唯一确定一个页
- FIL_PAGE_TYPE:这个代表当前页的类型
类型名称 十六进制 描述 FIL_PAGE_TYPE_ALLOCATED 0x0000 最新分配,还没有使用 FIL_PAGE_UNDO_LOG 0x0002 Undo日志页 FIL_PAGE_INODE 0x0003 段信息节点 FIL_PAGE_IBUF_FREE_LIST 0x0004 Insert Buffer空闲列表 FIL_PAGE_IBUF_BITMAP 0x0005 Insert Buffer位图 FIL_PAGE_TYPE_SYS 0x0006 系统页 FIL_PAGE_TYPE_TRX_SYS 0x0007 事务系统数据 FIL_PAGE_TYPE_FSP_HDR 0x0008 表空间头部信息 FIL_PAGE_TYPE_XDES 0x0009 扩展描述页 FIL_PAGE_TYPE_BLOB 0x000A 溢出页 FIL_PAGE_INDEX 0x45BF 索引页,也就是我们所说的数据页 - FIL_PAGE_PREV和FIL_PAGE_NEXT:InnoDB 以页为单位存储数据,若数据分散于多个不连续页,通过 FIL_PAGE_PREV 和 FIL_PAGE_NEXT 分别记录本页的上一页和下一页页号,构建双向链表将众多页串联,实现页在逻辑上连续而非物理上连续。
- FIL_PAGE_SPACE_OR_CHKSUM:代表当前页面的校验和
- 校验和定义:对于长字节串,通过某种算法计算出一个较短的值代表它,这个短值即校验和。比较长字节串前先比较校验和,若不同则长字节串肯定不同,可节省直接比较的时间
- FIL_PAGE_SPACE_OR_CHKSUM 属性:文件头部和尾部都有该属性,代表当前页面的校验和
- 作用原理:InnoDB 以页为单位处理数据,修改后需同步到磁盘。若同步一半断电致页传输不完整,可对比文件