变长字段的长度最大不可以超过 2 字节,这是因在 MySQL 数据库中 VARCHAR 类型的最大长度限制为 65535。变长字段之后的第二个部分是 NULL 标志位,该位指示了该行数据中是否有 NULL 值,有则用 1 表示。
接下来的部分是记录头信息(record header),固定占用5 字节(40 位)。每位含义见表:
名称 大小(bit) 描述() 1 未知
() 1 未知
deleted_flag 1 该行是否已被删除
min_rec_flag 1 如果该行记录是预定义为最小的记录,为1
n_owned 4 该记录拥有的记录数,用于Slot
heap_no 13 索引堆中该条记录的索引号
record_type 3 记录类型,000(普通),001(B+Tree节点指针),010(Infimum),011(Supremum)
next_record 16 页中下一条记录的相对位置
Total 40(5Byte) nothing
最后的部分就是实际存储每个列的数据。
需要特别注意的是,NULL 不占该部分任何空间,即 NULL 除了占有 NULL 标志位,实际存储不占有任何空间。另外有一点需要注意的是,每行数据除了用户定义的列外,还有两个隐藏列,事务 1D 列和回滚指针列,分别为 6 字节和 7 字节的大小。若 InnoDB 表没有定义主键,每行还会增加一个 6 字节的 rowid 列。
Redundant 是 MySQL 5 . 0 版本之前 InnoDB 的 行 记 录 存 储 方 式,这里就不展开。
2.2、行溢出数据InnoDB 存储引擎可以将一条记录中的某些数据存储在真正的数据页之外。因为一般数据页默认大小为16KB,假如一个数据页存储不了插入的数据,这时肯定就会发生行溢出。
一般认为 BLOB、LOB 这类的大对象列类型的存储会把数据存放在数据页之外。但是,BLOB 也可以不将数据放在溢出页面,而且即便是 VARCHAR 列数据类型,依然有可能被存放为行溢出数据。
3、InnoDB 数据页结构页是 InnoDB 存储引擎管理数据库最小磁盘单位。页类型为 B-tree Node 的页存放的即是表中行的实际数据了。
InnoDB 数据页由以下 7 个部分组成:
File Header (文件头)
Page Header (页头)
Infimun 和 Supremum Records
User Records (用户记录,即行记录)
Free Space (空闲空间)
Page Directory (页目录)
File Trailer (文件结尾信息)
其中 File Header、Page Header、File Trailer的大小是固定的, 分别为 38、56、8 字节,这些空间用来标记该页的一些信息,如 Checksum, 数据页所在 B+ 树索引的层数等。User Records、Free Space、Page Directory 这些部分为实际的行记录存储空间,因此大小是动态的。
参考:
【1】:《MySQL技术内幕 InnoDB存储引擎》
【2】:MySQL Architecture and Components
【3】:了解 MySQL的数据行、行溢出机制吗?
【4】:InnoDB数据页结构分析
【5】:InnoDB数据页结构
【6】:InnoDB -- 行记录格式