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_flag | B+树每层非叶子节点中最小目录项记录都会添加该标记 |
| 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个字节指向溢出列地址。
2. 数据页结构
2.1 数据页结构总览
2.2 记录在页中的存储
2.3 页目录