mysql基本存储单元是页,是服务器与磁盘交互的最小单位,默认大小16k,查看页大小:
show variables like 'innodb_page_size' =>16384
页中存储着多行数据,InnoDB引擎数据的存储格式也就是行格式有四种:
COMPACT
REDUNDANT
DYNAMIC
COMPRESSED
创建表时指定行格式:
CREATE TABLE XXX (XXX) ROW_FORMAT=COMPACT;
COMPACT行格式(5.6默认):
不定长字段长度列表
记录了所有列中的不定长度的列的长度列表,比如varchar(255),text,blob类型都是不定长度的,这个不定长度确切指的是字节而非字符,所以就算是char(10),当字符集为utf8时,字节长度在10-30之间,也是不定长的.比如有abc三个列,A类型varchar(10),B类型Int(11),C类型char(10) utf8,此时不定长字段长度列表里面就会记录A和C列的长度分别是多少,并且逆序存放,也就是存放C A列的长度,注意,如果不定长字段值为null,那么不会改列的长度.
NULL值列表
首先看有多少个可以为null的列,如果有三个的话,就以一个字节来表示,字节前5位补0,后三位就代表是这三个列是否为null,值为1就是null,值为0就是非null
头信息
compact头信息是固定5个字节组成,也就是40位,不同位有这不同的意思,如下图所示
aabcddddeeeeeeeeeeeeefffgggggggggggggggg
编号 | 名称 | 大小(位数) | 描述 |
---|---|---|---|
a | 预留位 | 2 | 暂时没有使用 |
b | deleted flag | 1 | 标记此行数据是否被删除 |
c | min_rec_flag | 1 | 如果是B树的非叶子节点,每层的最小记录(树最左边)节点会添加该标记 |
d | n_owned | 4 | 每个页中要给所有的数据行分组,分组中的最大行里面标记当前组中有多少行,组中其他的行n_owned为0 |
e | heap_no | 13 | 当前行在页面堆中的相对位置 |
f | record_type | 3 | 表示当前记录的类型,0位普通记录,1为非叶子节点,2为Infimum记录,3为Supremum记录 |
g | next_record | 16 | 表示一下条记录的相对位置 |
ROW_ID
如果表中没有指定主键,那么会找一个不允许为null的unique键做为主键,如果都没有,innodb就会自己为生成一个ROW_ID的隐藏列作为主键,否则不会生成这列.
TRX_ID
最新对该行记录进行更改的事务ID
ROLL_POINTER
回滚指针,指向更改之前的操作,用来事务进行回滚.
REDUNDANT行格式:
字段长度偏移列表
与COMPACT的不定长字段长度列表的区别是,后者是逆序依次记录变长字段的实际长度,而前者是逆序的所有列的偏移长度,比如有三个列,对应偏移量列表20 15 5
那么第一个字段的长度为5第二个的为10第三个的为5(逆序取差值)
NULL值列表
没有NULL值列表,是否为null值保存在字段长度偏移量的各个字段值二进制首位,为1时代表字段为null
头信息
redundant头信息是固定6个字节组成,也就是48位,不同位有这不同的意思,如下图所示
aabcddddeeeeeeeeeeeeeffffffffffghhhhhhhhhhhhhhhh
编号 | 名称 | 大小(位数) | 描述 |
---|---|---|---|
a | 预留位 | 2 | 暂时没有使用 |
b | deleted flag | 1 | 标记此行数据是否被删除 |
c | min_rec_flag | 1 | 如果是B树的非叶子节点,每层的最小记录(树最左边)节点会添加该标记 |
d | n_owned | 4 | 每个页中要给所有的数据行分组,分组中的最大行里面标记当前组中有多少行,组中其他的行n_owned为0 |
e | heap_no | 13 | 当前行在页面堆中的相对位置 |
f | n_field | 10 | 数据中的列的数量 |
g | 1byte_offs_flag | 1 | 0代表字段长度偏移列表每个列占2个字节,1时占一个字节 |
h | next_record | 16 | 表示一下条记录的相对位置 |
列溢出
如果列过大,如Blob,varchar,text等,一个页都存储不了(实际一个页至少要存储两条记录),就要用新的页去存储多出来的数据,针对这种大类型,COMPACT与REDUNDANT行格式,只会存储该列的前768个字节的数据以及一个指向溢出页(存储列多出来的数据的页)的地址.
DYNAMIC行格式(5.7默认)
show variables like '%row_format%' => dynamic
与COMPACT相比只是溢出列不再存储前768字节,而是只存储溢出页的地址
COMPRESSED行格式
与COMPACT相比只是溢出列不再存储前768字节,而是只存储溢出页的地址,并且会采用压缩算法对页面进行压缩.