InnoDB行、页记录存储结构

116 阅读3分钟

InnoDB有4种不同类型的行格式,分别是COMPACT,REDUNDANT,DYNAMIC和COMPRESSED,其中DYNAMIC是InnoDB默认使用的行格式。 这次主要介绍COMPACT行格式。

1.COMPACT类型行格式

一条完整的行记录,分为记录的额外信息和记录的真实数据两大部分。

1.1 记录的额外信息

记录的额外信息包括变长字段长度、NULL值列表和记录头信息。

  • 变长字段长度列表

Mysql支持的一些变长数据类型,如varchar(M)等,因其存储字节的大小不是固定的,所以需要把这些数据占用的字节数存起来,并且是逆序存放。

  • NULL值列表

一条记录中的列可能存储很多NULL值,如果把这些NULL都放在记录的真实数据中会占用很多地方,COMPACT行格式将NULL值统一管理。

首先统计表中允许存储NULL值的列有哪些。将主键和设置列为NOT NULL的都排除了。然后,将每个允许存储NULL值的列对应一个二进制位,二进制 按照 列的逆序 排列,二进制位为1时,代表该列的值为NULL为0时,代表该列值不为NULL。

  • 记录头信息

记录头信息由固定的5个字节组成,用以描述记录的一些属性。

名称描述
deleted_flag标记该记录是否被删除
min_rec_flagB+树每层非叶子节点中最小目录项记录都会添加该标记
n_owned一个页面会分为若干个组,每个组中有一个记录是“组长”,组长记录的n_owned值代表该组中所有记录的条数,其他记录都记录为0
record_type表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点的目录项记录,2表示Infimum记录,3表示Supremum记录
next_record表示下一条记录的相对位置

1.2 记录的真实数据

记录的真实数据,除了会记录可视的列外,mysql会为每个记录默认的添加一些隐藏列,具体如下: Innodb表的主键生成策略:优先使用用户定义的主键,若用户未定义,则选取一个不允许为NULL的UNIQUE键作为主键;若也没有,则innodb会默认为表添加名为row_id的隐藏列作为主键。

1.3 溢出列

InnoDB是以页为单位来管理存储空间的,每个页的大小为16KB。对于占用空间非常多的列,不同的行行格式类型处理方式不同。在COMPACT行格式中,它会先存储前768字节,再把剩余的数据分散存储到其他的页中,然后在真实数据处用20个字节存储指向这些页的地址。在DYNAMIC行格式中,它不会在真实数据处存储该溢出列的真实数据的前768字节,而是把该列所有的真实数据都存储到溢出页中,只在记录的真实数据处用20个字节指向溢出列地址。

微信图片_20220723163443.jpg

2. 数据页结构

2.1 数据页结构总览

2.2 记录在页中的存储

2.3 页目录