InnoDB将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16KB。
行格式
Compact
变长字段列表
1. `VARCHAR(M)`、`VARBINARY(M)`、各种`TEXT`类型,各种`BLOB`类型等变长字段占用的存储空间分为两部分:【真正的数据内容】和【占用的字节数】
1. 只存储值为非 *NULL* 的列内容占用的长度,各变长字段数据占用的字节数按照列的顺序逆序存放。
1. 并不是所有记录都有变长字段长度列表部分,如果表中所有的列都不是变长的数据类型的话,这一部分就不需要有。
-
NULL 值列表
-
将每个允许存储
NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列,二进制位的值为1时,代表该列的值为NULL。二进制位的值为0时,代表该列的值不为NULL。 -
主键列、被
NOT NULL修饰的列在统计的时候不会把这些列算进去。 -
如果表中没有允许存储
NULL的列,则NULL值列表不存在。
-
-
记录头信息
| 名称 | 大小(单位:bit) | 描述 |
|---|---|---|
预留位1 | 1 | 没有使用 |
预留位2 | 1 | 没有使用 |
delete_mask | 1 | 标记该记录是否被删除 |
min_rec_mask | 1 | B+树的每层非叶子节点中的最小记录都会添加该标记 |
n_owned | 4 | 表示当前记录拥有的记录数 |
heap_no | 13 | 表示当前记录在记录堆的位置信息 |
record_type | 3 | 表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录 |
next_record | 16 | 表示下一条记录的相对位置 |
-
记录的真实数据
-
-
MySQL 会为每个记录默认的添加一些隐藏列。
-
列名 是否必须 占用空间 描述 DB_ROW_ID 否 6字节 行ID,唯一标识一条记录 DB_TRX_ID 是 6字节 事务ID DB_ROLL_PTR 是 7字节 回滚指针 -
InnoDB 表对主键的生成策略:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个 Unique 键作为主键,如果表没有定义 Unique 键,则为表默认添加一个名为
DB_ROW_ID的隐藏列作为主键。 -
对于 CHAR(M) 类型的列来说,当列采用的是定长字符集时,该列占用的字节数不会被加到变长字段长度列表,而如果采用变长字符集时,该列占用的字节数也会被加到变长字段长度列表。
-
Redundant
Dynamic & Compressed
- 5.7 版本的默认行格式就是
Dynamic - 不会在记录的真实数据处存储字段真实数据的前 768 个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址
- Compressed 行格式和 Dynamic 不同的一点是,Compressed 行格式会采用压缩算法对页面进行压缩,以节省空间。