InnoDB页
MySQL数据是存储在物理的磁盘上的,而我们通过存储引擎对数据进行操作的时候就需要将磁盘上的数据加载到内存中去。如果一条一条将数据从磁盘加载到内存那么效率会非常的低,因此InnoDB将数据划分为多个页,以页为单位数据从磁盘加载到内存,一页为16KB(这个参数是通过innodb_page_size系统变量指定的,只有mysql在第一次初始化数据目录的时候可以指定)。也就是说内存与磁盘进行一次数据交互的最小为16KB。
InnoDB行格式
我们平时都是以记录为单位来存储数据的,这些记录在磁盘上的格式称之为行格式或记录格式。MySQL的默认存储引擎InnoDB有四种行格式COMPACT,REDUNDANT,DYNAMIC,COMPRESSED。
指定记录使用的行格式
create tabel 表名 (列信息) row_format=行格式名称
||alter table 表名 row_format=行格式名称
COMPACT
从上图可知完整的记录包括真实的记录数据和额外的信息。
额外记录信息
-
变长的字段长度
在MYSQL中出来固定长度的数据类型,还有一些数据类型的长度是可变的如varchar(M),这些字段的存储所需要的字节数是不固定的,所以我们在存储数据的时候也要将其需要的字节数存储起来。
当变长字段不为NULL时则将其占用字节长度信息记录在额外记录信息的首部,且根据记录列的顺序逆序排序。
如果字符集本身是变长的,那么char(M)这种固定类型的也会被放进去。
-
NULL值列表
在记录中有一些数据为NULL,如果将其存放在真实数据则比较占用地方,所以将NULL值统一管理,存储在NULL值列表。
- 首先统计表中允许为NULL值的列表有哪些
- 如果没有则不存在NULL值列表,反之将每个允许为NULL的列对应一个二进制位(1表示值为NULL,0表示不为NULL),二进制为按照列的顺序逆序排序。
- 查看二进制列是否构成整数(字节整数)。不足则在最高位补0;
-
记录头信息
记录头信息有固定5个字节组成,用来描述记录的一些属性。
真实数据
真实的数据列中除了我们记录中的字段列以外还会额外的增添一些隐藏列。
列名 | 是否必须 | 占用空间 | 描述 |
---|---|---|---|
row_id(DB_ROW_ID) | no | 6字节 | 行ID,标识唯一一条记录(没有主键时且不存在UNIQUE的字段生成) |
trx_id(DB_TRX_ID) | yes | 6字节 | 事务Id |
roll_pointer(DB_ROLL_PTR) | yes | 7字节 | 回滚指针 |
溢出列
InnoBD是一页进行数据交互的,一页也不过16KB,但是有些列所占用的字节数非常大,超过了页本身容量,这时候就需要存储到其他的页中。
COMPACT会存储数据超出列的前768个字节,使用20个字节指向其他页地址,存放溢出数据的的页也成为溢出页。
REDUDANT行格式
这是5.0之前的格式,这里就不多介绍了。
DYNAMIC/COMPRESSED行格式
5.7版本的默认行格式就是DYNAMIC。
他们只有在处理溢出列的时候有所不同
- DYNAMIC:将该列所有的真实数据都记录在溢出页中,只在记录真实数据处使用20个字节大小指向一溢出页。
- COMPRESSED:在溢出页中会使用压缩算法。