行格式简介
表的行格式决定了其行的物理存储方式,进而会影响查询和DML操作的性能。
InnoDB存储引擎支持四种行格式:REDUNDANT、
COMPACT、
DYNAMIC
、COMPRESSED。
MySQL版本5.7默认使用DYNAMIC
行格式。
InnoDB行格式概述
行格式 | 紧凑的存储 | 增强的可变长度色谱柱存储 | 大索引键前缀支持 | 压缩支持 | 支持的表空间类型 | 所需文件格式 |
REDUNDANT | No | No | No | No | system, file-per-table, general | Antelope or Barracuda |
COMPACT | Yes | No | No | No | system, file-per-table, general | Antelope or Barracuda |
DYNAMIC | Yes | Yes | Yes | No | system, file-per-table, general | Barracuda |
COMPRESSED | Yes | Yes | Yes | Yes | file-per-table, general | Barracuda |
DYNAMIC
行格式介绍
DYNAMIC
行格式由变长字段列表 + NULL值列表 + 记录头信息 + 列值组成。
1.变长字段长度列表
比如VARCHAR(M)
类型的列称为变长字段,其真实数据存在列值,而占用的字节长度(十六进制表示)逆序存在变长字段长度列表。
2.NULL值列表
将每个允许存储NULL
的列对应一个二进制位,二进制位按照列的顺序逆序排列,如果列值为NULL则记录
1到NULL值列表。不为NULL则记录0。
3.记录头信息
它是由固定的5
个字节组成。5
个字节也就是40
个二进制位。
记录头信息
名称 | 大小(B) | 描述 |
预留位 | 2 | 未使用 |
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 | 表示下一条记录的相对位置 |
4.列值
列值分为隐藏列和真实数据列。
隐藏列为ROW_ID(行ID)、TRX_ID(事务ID)、ROLL_PTR(回滚指针)。
真实数据列为用户表中的值。
其他行格式和DYNAMIC差不多,
只是对行溢出处理方式不同,DYNAMIC
行溢出是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址,COMPACT是
记录的真实数据处存储字符串的前768个字节,COMPRESSED
会采用压缩算法对页面进行压缩,以节省空间。
那么对于一个表
学生成绩表
id | name | score |
1 | 穗乃果 | 12 |
2 | 鸟 | 60 |
3 | 海未 | |
真实存储形式是这样的
学生成绩表
变长字段列表 | NULL值列表 | 记录头信息 | 行ID | 事务ID | 回滚指针 | id | name | score |
2 3 | 0 | 忽略 | 10 | 2 | 1 | 穗乃果 | 12 | |
2 1 | 0 | 忽略 | 32 | 56 | 2 | 鸟 | 60 | |
2 | 2 | 忽略 | 33 | 80 | 3 | 海未 |
实际值都是十六进制表示,这里只是为了方便阅读。行ID(row_id)当表中没有唯一主键索引和非空的唯一索引才会存在。