1.InnoDB页的简介
页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位。常见的页类型有数据页、Undo 页、系统页、事务数据页等
2.InnoDB行的存储格式
我们插入MySQL的记录在InnoDB中可能以4中行格式存储,分别是Compact、Redundant、Dynamic和Compressed行格式,我们可以在创建或修改表的语句中指定我们想要的行格式
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称ALTER TABLE 表名 ROW_FORMAT=行格式名称
2.1 COMPACT行格式
Compact行记录是在MySQL5.0中引入的,为了高效的存储数据,简单的说,就是为了让一个页(Page)存放的行数据越多,这样性能就越高
一条完整的记录被分为记录的额外信息和记录的真实数据两大部分
2.1.1 记录的额外信息
这些额外信息分为3类,分别是变长字段长度列表、NULL值列表和记录头信息。
2.1.1.1 变长字段长度列表
逆序记录每一个列的长度,如果列的长度小于 255 字节,则使用一个字节,否则使用 2 个字节。该字段的实际长度取决于列数和每一列的长度,因此是变长的
2.1.1.2 NULL值列表
一个字节,表示该行是否有 NULL 值。注意:此处需要注意固定长度 CHAR 数据类型和变长 VCHAR 数据类型在 Compact 记录下为 NULL 时不占用任何存储空间。
2.1.1.3 记录头信息
用于描述记录的记录头信息,它是由固定的5个字节组成。5个字节也就是40个二进制位,不同的位代表不同的意思,其中 next_record 记录了下一条记录的相对位置,一个页中的所有记录使用这个字段形成了一条单链表。
2.1.2 记录的真实数据
MySQL会为每个记录默认的添加一些列,除了记录每一列对应的数据外,还有隐藏列,它们分别是 Transaction ID、Roll Pointer 以及 row_id(当没有指定主键)
2.1.2.1 row_id
当用户没有设置主键,并且没有unique属性时,innoDB会隐式的生成一个row_id,作为主键
2.1.2.2 transaction_id 和 roll_pointer
用来记录当前记录的事务号,用于可重复读隔离级别的乐观锁实现
2.2 Redundant行格式
MySQL5.0之前的行记录格式:
2.2.1 字段长度偏移列表
与 Compact 中的变长字段长度列表相同的是它们都是按照列的逆序顺序设置值的,不同的是字段长度偏移列表记录的是偏移量,每一次都需要加上上一次的偏移,同时对于 CHAR 的 NULL 值,会直接按照最大空间记录,而对于 VCHAR 的 NULL 值不占用任何存储空间。
与compact行格式的不同在于:
- 存储的是所有属性的长度
- 长度是通过两个相邻偏移量的差计算得出的
- 使用了每个列对应偏移量的第一位作为NULL比特位来标记空值,并且对于真实记录为NULL的定长字段也要使用0比特填充,变长则不用
- 对于char(M)来说,即使使用变长字符集,通通按照字符集的最大字符长度来分配空间
2.2.2 记录头信息
和compact的大致相同
行溢出数据
我们知道数据页的大小是 16KB,Innodb 存储引擎保证了每一页至少有两条记录,当行记录的长度没有超过行记录最大长度时,所有数据都会存储在当前页。如果一页当中的记录过大,会截取前 768 个字节存入页中,其余的放入 BLOB Page。
然后记录的真实数据处用20个字节存储指向这些页的地址(当然这20个字节中还包括这些分散在其他页面中的数据的占用的字节数),从而可以找到剩余数据所在的页
2.3 Dynamic和Compressed行格式
InnoDB1.0x开始引入心的文件格式(file format,用户可以理解位新的页格式)——Barracuda,这个新的格式拥有两种新的行记录格式:Compressed和Dynamic。
新的两种记录格式对于存放BLOB中的数据采用了完全的行溢出的方式。
-
Dynamic行格式,列存储是否放到off-page页,主要取决于行大小,他会把行中最长的一列放到off-page,直到数据页能存放下两行。TEXT或BLOB列<=40bytes时总是存在于数据页。这种方式可以避免compact那样把太多的大列值放到B-tree Node(数据页中只存放20个字节的指针,实际的数据存放在Off Page中,之前的Compact 和 Redundant 两种格式会存放768个字前缀字节)。
-
Compressed物理结构上与Dynamic类似,Compressed行记录格式的另一个功能就是存储在其中的行数据会以zlib的算法进行压缩,因此对于BLOB、TEXT、VARCHAR这类大长度数据能够进行有效的存储(减少40%,但对CPU要求更高)。