Innodb 文件结构分析 (三) row format 以及字符集

从两个参数入手:

mysql> show variables like '%row_format%';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| innodb_default_row_format | dynamic |
+---------------------------+---------+
1 row in set (0.00 sec)

mysql> show variables like '%file_format%';
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_file_format       | Barracuda |
| innodb_file_format_check | ON        |
| innodb_file_format_max   | Barracuda |
+--------------------------+-----------+
3 rows in set (0.00 sec)

mysql> 

这里是5.7 的版本,在 8 的版本里 innodb_file_format 已经废弃,这样举例是把所有的格式都做下总结;首先看文件的格式,在mysql前后出现过两种文件格式:

antelope: 是早期的Mysql文件格式,它支持两种方式的行记录格式compact 和redundant ;

barracude:是后期新的文件格式,它支持两种行记录格式分别是compress和dynamic;其中compress 参数只能用于在创建表时;而不能指定为系统的行格式,因为系统表空间并不支持压缩存储;

从数量上说总共有4种 row 格式,实际是dynamic和compact的区别非常小,所以也可以看做是三种格式,首先来看看 redundant格式:

  • Redundant

row1

如图所示一个完整的行记录,主要包含如下部分:

offset array:此部分为变长,其作用是指出从 origin 处开始的,列的偏移量;每个列的偏移量由1byte或者2byte表示;此数组列表中的每个元素的具体长度由 6-byte bit field 中的1byte_offs_flag 值决定;

6-byte bit field,又称为REC_N_OLD_EXTRA_BYTES,是固定长度 6byte,其主要记录列的相关信息,每个bit位的具体意思如下:

row2

hidden field 实际由三个部分组成:primary key/DB_ROW_ID,如果是后者为定长 6bytes;DB_TRX_ID 事务id,定长6byte,DB_ROLL_PTR 回滚段地址,定长7bytes;

其余为具体的表定的其它列,这里要说明的是如果表没有加主键,那么系统会自动生成 6byte的 DB_ROW_ID作为主键,那么Column1 就是行的第一列,如果表在创建时添加了主键,那么此处Column1就是行记录的第二列;

  • compact/dynamic

compact 和dynamic 格式的行记录基本是相同的,只是在不同的数据类型存储上,dynamic有更优秀之处,其主要组成部分为:

row4

offset array:此处为变长部分,记录具体列的长度,数值的每个元素长度为1byte或者2byte,具体是由列的类型定义长度与实际存储长度决定的,详细可以参考:http://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html

Null bit field:每个bit代表一个null 列,所以null 列的个数决定了此部分的长度;null 列不占用空间;

5byte bit field:也就是REC_N_NEW_EXTRA_BYTES 

row5

其余部分与前者同;

dynamic 与compact的两种格式的区别在于:blob 的存储上,dynamic 只存储前20byte 在row 中,而compact 存储前768 byte; 这样dynamic格式更灵活;对于多列也有很多好处;

字符集实际就是 字符能够被计算机软硬件识别的组织方式;不同的字符集的组织形式是不一样的,比如ASCII,是每个字符一个byte,用其中的7bit进行表示,以0–127 代表一个字符,而Unicode 是用整数,两byte –16bit代表一个字符的,所以了解字符集对于数据的解析是非常有好处的;由于不同的字符集导致字符占用的实际存储长度也不同,所以在进行数据的解析,迁移等等操作时,需要更好的考虑字符集带来的影响;