Compact行格式总结
参考自 https://www.cnblogs.com/wade-luffy/p/6289183.html 感恩原作者
InnoDb行格式如下
现在从 https://www.cnblogs.com/wade-luffy/p/6289183.html 具体看一下这部分是怎么存储的
create table mytest ( t1 varchar(10), t2 varchar(10), t3 char(10), t4 varchar(10) ) engine=innodb charset=latin1 row_format=compact; insert into mytest values('a','bb','bb','ccc'); insert into mytest values('d','ee','ee','fff'); insert into mytest values('d',NULL,NULL,'fff');
0000c070 73 75 70 72 65 6d 75 6d 03 02 01 00 00 00 10 00|supremum…… 0000c080 2c 00 00 00 2b 68 00 00 00 00 00 06 05 80 00 00|,……+h…… 0000c090 00 32 01 10 61 62 62 62 62 20 20 20 20 20 20 20|.2..abbbb 0000c0a0 20 63 63 63 03 02 01 00 00 00 18 00 2b 00 00 00|ccc……+…… 0000c0b0 2b 68 01 00 00 00 00 06 06 80 00 00 00 32 01 10|+h……2.. 0000c0c0 64 65 65 65 65 20 20 20 20 20 20 20 20 66 66 66|deeeefff 0000c0d0 03 01 06 00 00 20 ff 98 00 00 00 2b 68 02 00 00|……+h…… 0000c0e0 00 00 06 07 80 00 00 00 32 01 10 64 66 66 66 00|……2..dfff. 该行记录从0000c078开始,若整理如下,相信你会有更好的理解: 03 02 01/*变长字段长度列表,逆序*/ 00/*NULL标志位,第一行没有NULL值*/ 00 00 10 00 2c/*记录头信息,固定5字节长度*/ 00 00 00 2b 68 00/*RowID我们建的表没有主键,因此会有RowID*/ 00 00 00 00 06 05/*TransactionID*/ 80 00 00 00 32 01 10/*Roll Pointer*/ 61/*列1数据'a'*/ 62 62/*列2'bb'*/ 62 62 20 20 20 20 20 20 20 20/*列3数据'bb'*/ 固定长度char字段在未填充满其长度时,会用0x20来进行填充 63 63 63/*列4数据'ccc'*/
现在我们关注有NULL值的第三行: 03 01/*变长字段长度列表,逆序*/ 06/*NULL标志位,第三行有NULL值*/ 00 00 20 ff 98/*记录头信息*/ 00 00 00 2b 68 02/*RowID*/ 00 00 00 00 06 07/*TransactionID*/ 80 00 00 00 32 01 10/*Roll Pointer*/ 64/*列1数据'd'*/ 66 66 66/*列4数据'fff'*/ 第三行有NULL值,因此NULL标志位不再是00而是06了,转换成二进制为00000110,为1的值即代表了第2列和第3列的数据为NULL,在其后存储列数据的部分,我们会发现没有存储NULL,只存储了第1列和第4列非NULL的值。这个例子很好地说明了:不管是char还是varchar类型,NULL值是不占用存储空间的。
这里请注意下,尽量不要让一行有NULL值,应该使用NOT NULL DEFAULT。大量的NULL会影响索引稳定性
记录头信息格式如下
1.delete_mask:表示该行记录是否被删除其实就是删除记录的标识位并占用一个二进制位,其中0--未删除 1--已删除
2.heap_no:表示当前记录在该页中的位置,除此之外heap_no中还存在两条虚拟记录行用于记录当前页中最大记录和最小记录的主键值
3.next_record:表示当前记录的真实数据到下一条记录的真实数据的地址偏移量,其实这就是个单项链表,可以通过一条记录找到下一条记录。但值得注意的是下一条记录并不是我们插入顺序的下一条记录而是按照主键值由小到大的顺序的下一条记录。而且规定最小记录的下一条记录就是本页中存储的主键值最小的记录,而本页中主键值最大的记录的下一条记录就是本页中的最大记录
额外信息
行数据还包括了隐藏的两个字段,事务ID和Undo log指针。6字节的事务ID列和一个7字节的回滚段指针。