上篇文章介绍了InnoDB的compact列类型,存储数据分为真实数据,和额外信息,而额外信息分为变长字段长度列表,null值列表,记录头信息,而变长字段长度列表是要记录varchar,text等长文本,char这种则不存储,当数据为null也不存储,ascii的字节长度为1,乘以varchar(m)的最长字符创长度,1*M若小于255,则用一个字节存储字段长度,若大于255,当真实数据长度小于127,则一个字节存储,大于则两个字节存储最长字段长度。
InnoDB变长字段长度列表(1)--mysql从入门到精通(六)
NULL值列表
Compact行格式的null并不是存储在真实数据里,为了提高效率,这些null值统一存储在变长字段长度列表的后面null列表里。
1、首先是看看有哪些null字段,比如被not null修饰,都是不需要存储到null值列表的。
2、如果表没有可以存储null的字段,则null值列表也不会存在,当前列表存储数据的时候,也是和变长字段长度列表一样,按逆序排列。
因为compact_tb表中有三个字段可以存储null,c1,c3,c4,因为逆序排列,所以存储进去就是c4,c3,c1。
Mysql规定null值列必须用整个字节位表示,一个字节有 8个字节为,因为表里有三个可以为null的字段,所以剩下五个直接补0,存储的效果就是00000c4c3c1。如果有9个可以为null的字段,则需要两个字节来表示。带入表中我们可以看到,第一行三个字段都有数据,所以为00000000转为十六进制就是0x00。第二行有c3和c4都为null,所以存储为00000110,转为十六进制就是0x06。
第一行存储的为:010304,00
第二行存储的为:0304,06
记录头信息
除了变长字段长度列表和null值列表外,额外信息还有一个记录头信息。他和前面两个不同,都是由不同的情况,则用一个节或者两个节存储数据,记录头信息则是规定的五个节存储数据,五个节也就是40个二进制位,不同的位代表不同的意思。
预留位1:1bit,没有使用。
预留位2:1bit,没有使用。
Delete_mask:1bit,标记该记录是否被删除。
Min_rec_mask:1bit,B+树的每层非子叶节点中的最小记录都会添加该标记。
N_owned:4bit,表示当前记录拥有的记录数。
Heap_no:13bit,表示当前记录在记录堆的位子信息。
Recode_type:3bit,表示当前记录类型,0表示普通记录,1表示B+树非子叶节点记录,2表示最小记录,3表示最大记录。
Next_record:16bit,表示下一条记录相对位置。
后面文章给大家一一详细介绍这些位子。