MySQL——InnoDB记录(行)格式
1、设置记录格式
我们平时的数据以行为单位来向表中插入数据,这些记录在磁盘上的存放方式也被称为行格式或者记录格式。InnoDB存储引擎设计了4种不同类型的行格式,分别是Compact,Redundant, Dynamic 和 Compressed 行格式。
其中 Compact 和 Redundant 两种存放行记录数据格式是MySQL 5.1后提供的。
Compact 行格式是MySQL5.1后的默认格式。Redundant 格式是MySQL5.0之前InnoDB的行记录存储方式,是为了兼容之前的版本而保留。Redundant 属于渐渐被抛弃的格式。
但在 MySQL 5.7.9 及以后版本,默认行格式由innodb_default_row_format变量决定,它的默认值是 Dynamic
查看MySQL 5.7默认记录格式

查看具体表使用的的记录格式
-- 查看test1表使用的的记录格式
show table status like 'test1'\G;

指定行格式的语法
在创建和修改表的语句中指定行格式:
- CREATE TABLE表名(列的信息)ROW_FORMAT=行格式名称
- ALTER TABLE表名ROW_FORMAT=行格式名称
2、Compact 行格式
Compact行格式是在MySQL5.0中引入的,为了高效的存储数据,简单的说,就是为了让一个页(Page)存放的行数据越多,这样性能就越高。
Compact 行格式示意图如下:

1、变长字段长度列表:变长的数据类型(VARCHAR、VARBINARY、TEXT)修饰的列称为变长字段,变长字段长度最大不超过2字节(MySQL数据库varcahr类型的最大长度限制为65535)。Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表。
2、NULL值列表:该位指示了该行数据中是否有NULL值,Compact行格式会把可以为NULL的列统一管理起来,存在一个标记为NULL值列表中。如果表中没有允许存储 NULL 的列,则 NULL值列表也不存在了。
- 二进制位的值为1时,代表该列的值为 NULL
- 二进制位的值为0时,代表该列的值不为 NULL
3、记录头信息:固定占用5字节(40位)
4、记录的真实数据:实际存储每列的数据,NULL不占该部分任何空间,即NULL占有NULL标志位,实际存储不占任何空间。记录的真实数据除了实际存储每列的数据外,还会有三个隐藏列:
| 列名 | 是否必须 | 占用空间 | 描述 |
|---|---|---|---|
| row_id | 否 | 6字节 | 行ID,唯一标识一条记录 |
| transaction_id | 是 | 6字节 | 事务ID |
| roll_pointer | 是 | 7字节 | 回滚指针 |
一个表没有手动定义主键,则会选取一个Unique键作为主键,如果连Unique键都没有定义的话,则会为表默认添加一个名为row_id 的隐藏列作为主键。所以row_id是在没有自定义主键以及Unique键的情况下才会存在的。
3、行溢出
一个数据页默认大小为16KB,换算成byte: 16 * 1024 = 16384 byte,
而一个varchar类型的列最多可以存储65533(除了变长字段长度的两个字节)个字节,这样就可能出现一个数据页存放不了一条记录,这种现象称为行溢出。
Dynamic、Compressed 行格式和 Compact行格式挺像,只不过在处理行溢出数据时有分歧:
-
在 Dynamic 和 Compressed 行格式中,当行记录的长度没有超过行记录最大长度时,所有数据都会存储在当前页。当行记录的长度超过行记录最大长度时,变长列(variable-length column)会选择外部溢出页(overflow page,一般是Uncompressed BLOB Page)进行分页存储。
-
Compact 和 Redundant 两种行格式保留前768Byte在当前页(B+Tree叶子节点),其余数据存放在溢出页。768Byte后面跟着20Byte的数据,用来存储指向溢出页的指针。
Compressed 行记录格式的另一个功能就是,存储在其中的行数据会以zlib的算法进行压缩,因此对于BLOB、TEXT、VARCHAR这类大长度类型的数据能够进行非常有效的存储
4、Redundant 行格式
Redundant 格式是MySQL5.0之前InnoDB的行记录存储方式,是为了兼容之前的版本而保留。
Redundant 格式示意图:

不同于 Compact 行记录格式,Redundant 行记录格式的首部是一个字段长度偏移列表,同样是按照列的顺序逆序放置的。
字段长度偏移列表 和 变长字段长度列表 的区别:
- Redundant 行格式会把该条记录中所有列(包括隐藏列)的长度信息都按照逆序存储到字段长度偏移列表。
- Redundant 行格式计算列值长度的方式不像 Compact行格式那么直观,它是采用两个相邻数值的差值来计算各个列值的长度。
Redundant 行格式的记录头信息
Redundant 行格式的记录头信息固定占用6个字节,
与 Compact行格式的记录头信息相比有两处不同:
- Redundant行格式多了n_field 和1byte_offs_flag这两个属性。
- n_field:记录中列的数量
- 1byte_offs_flag:记录字段长度偏移列表中每个列对应的偏移量
- Redundant行格式没有record _type这个属性。
本文深入探讨了MySQL InnoDB存储引擎的行格式,包括Compact、Redundant、Dynamic和Compressed。重点解析了Compact行格式的结构,如变长字段长度列表、NULL值列表和记录头信息,并介绍了行溢出的概念。同时,提到了Redundant行格式的特征,如字段长度偏移列表。了解这些行格式有助于优化数据库存储和提高性能。
1508

被折叠的 条评论
为什么被折叠?



