InnoDB记录结构浅析

InnoDB记录由三个部分组成,见表1

1 InnoDB 的记录组织形式
名称
长度
Field Start Offsets
F*1 或者  (F*2) 个字节
Extra Bytes
6 个字节
Field Contents
和记录的实际内容相关
备注:
1)         F ”是指记录的字段数量。
2)         Field Start Offsets ”是一个目录列表,分别指向下一个字段实际存储的偏移值。
3)         Extra Bytes ”的长度是不变的,占用 6 个字节。
4)         Field Contents ”存放实际的数据。
   记录的起点实际上是从“ Field Contents ”的第一个字节开始的,而不是从“ Field Start Offsets ”的第一个字节开始。如果得到一个记录的指针,实际是指向实际记录的起点。因此,如果要得到其它两个部分,只要对指针进行减法操作就行了。比如减去 6 就得到“ Extra Bytes ”的起始地址。只有第三部分,是采用对指针的加法操作来得到相应的字段地址偏移。
 
1 FIELD START OFFSETS(字段偏移量列表)
    这是一个目录列表,每一个目录是一个相对于记录起点的偏移量。这些目录是反向存储的,也就是说第一个字段的偏移量是存储在该列表的最后一个目录。
   举个例子:假设现在有三个列。第一个列的长度是 1 ,第二个列的长度是 2 ,第三个列的长度是 4 。在这种情况下,相应的偏移量分别是: 1 3(1+2) 7(1+2+4) 。但是因为目录列表是反向存储的,所以存储的内容为: 07 03 01
  这里面有两种特殊的情况需要考虑:
1)         每个目录的长度或者为 1 个字节或者为 2 个字节。只有当记录的总长度小于 127 时,才可以设置目录长度为 1 个字节。在“ Extra Bytes ”中会指出目录的长度是一个字节还是两个字节。
2)         偏移值的最高位通常是标志位。
 
当每个偏移量是一个字节时:
1)         1 bit=0 :字段是非 NULL =1 :字段是 NULL
2)         7 bits :实际的偏移值,范围是 0 127
 
当每个偏移量是两个字节时:
1)     1 bit=0 :字段是非 NULL =1 :字段是 NULL
2)     1 bit=0 :字段存储在同一页, =1 :字段存储在不同的页,只有当记录包含大字段对象时才可能出现这一情况。。
3)     14 bits :实际的偏移值,范围是 0 16383
 
2 EXTRA BYTES(额外字节)
  额外字节是定长的,占用 6 个字节。见表 2
2 extra bytes 的组织形式
名称
长度
描述
info_bits
 
 
()
1 bit
没有使用
()
1 bit
没有使用
delete_flag
1 bit
当记录已被删除,设置该标志位为 1
min_rec_flag
1 bit
如果是最小虚拟记录,设置该标志位为 1
n_owned
4 bits
该记录拥有的记录数量
heap_no
13 bits
在索引页的堆中的序号
n_fiels
10 bits
该记录拥有的字段数量,范围为 1 1023
1bytes_offs_flag
1 bit
如果“ Files Start Offsets ”是 1 字节的,则设为 1
next 16 bits
16 bits
指向该页的下一条记录
total
48 bits
 
  如果你仅仅打算读取该记录,那么标志位“ 1byte_offs_flag ”必须得读的,因为你需要知道目录指针是 1 字节的还是 2 字节的。
  当给定记录的起点指针(即指向“ Field Contents ”),得到目录列表头指针(即指向“ Field Start Offsets ”)的步骤如下:
1)  X=n_fields (该数值和目录列表的数量相等)
2) 如果 1byte_offs_flag 等于 0 ,就是说每个偏移量需要 2 个字节表示,那么 X=X+2
3)  X=X+6 ,因为“ Extra Bytes ”为 6 个字节。
4)  所以目录列表头指针的地址,等于记录的起始指针减去 X
 
3 FIELD CONTENTS(字段内容)
  这个部分用来存放记录的实际数据,按照定义的顺序进行存放。
 
 
 
举例
  创建一张表:
 create table t(field1 varchar(3),field2 varchar(3),field3 varchar(3));
  尽管在定义中我们只提供了三个列(字段),但实际记录中包含六个列,因为系统自动增加了三个系统列用于管理。三个系统列分别为: ROWID 、事务 ID 、会滚段指针。在这个例子中,我们不考虑这三个列。
  插入三条数据:
 insert into t values('PP','PP',  'PP');
 insert into t values('QQ','QQ',  'QQ');
insert into t values('R',NULL,  NULL);
  通过 dump 工作可以得到以下的实际存储数据,见表 3
  物理存储中记录的组织形式
Address Values in Hexadecimal
Values in ASCII
0D4280: 00 00 2D 00 84 4F 4F 4F 4F 4F 4F 4F 4F 4F 19 17
..-..OOOOOOOOO..
0D4290: 15 13 0C 06 00 00 78 0D 02 BF 00 00 00 00 04 21
......x........!
0D42A0: 00 00 00 00 09 2A 80 00 00 00 2D 00 84 50 50 50
.....*....-..PPP
0D42B0: 50 50 50 16 15 14 13 0C 06 00 00 80 0D 02 E1 00
PPP.............
0D42C0: 00 00 00 04 22 00 00 00 00 09 2B 80 00 00 00 2D
....".....+....-
0D42D0: 00 84 51 51 51 94 94 14 13 0C 06 00 00 88 0D 00
..QQQ...........
0D42E0: 74 00 00 00 00 04 23 00 00 00 00 09 2C 80 00 00
t.....#.....,...
0D42F0: 00 2D 00 84 52 00 00 00 00 00 00 00 00 00 00 00
.-..R...........
 
对记录进行重新编排,格式如下所示:
19 17 15 13 0C 06 Field Start Offsets /* First Row */
00 00 78 0D 02 BF Extra Bytes
00 00 00 00 04 21 System Column #1
00 00 00 00 09 2A System Column #2
80 00 00 00 2D 00 84 System Column #3
50 50 Field1 'PP'
50 50 Field2 'PP'
50 50 Field3 'PP'
 
16 15 14 13 0C 06 Field Start Offsets /* Second Row */
00 00 80 0D 02 E1 Extra Bytes
00 00 00 00 04 22 System Column #1
00 00 00 00 09 2B 80 System Column #2
00 00 00 2D 00 84 System Column #3
51 Field1 'Q'
51 Field2 'Q'
51 Field3 'Q'
 
94 94 14 13 0C 06 Field Start Offsets /* Third Row */
00 00 88 0D 00 74 Extra Bytes
00 00 00 00 04 23 System Column #1
00 00 00 00 09 2C System Column #2
80 00 00 00 2D 00 84 System Column #3
52 Field1 'R'
  现在我们对记录进行分析:
1) 对于第一条记录的六个字段,长度分别为: 6 6 6 2 2 2 。因为每一个偏移量是针对下一个字段的,所以对应的 16 进制偏移值为: 06 0c (6+6) 13(6+6+7) 15(6+6+7+2) 17(6+6+7+2+2) 19(6+6+7+2+2) 。因为目录列表是反序的,所以存储的值是: 19 17 13 0c 06
2 )我们再看第一条记录的“ Extra Bytes ”部分: 00 00 78 0D 02 BF 。第四个字节的 0D 表示二进制是 1101 110 n_filed 的最后三个 bits (继续往前面分析, n_files 对应的二进制为 0000000110 ,也就是 6 ,说明该记录由 6 个字段组成), 1101 的最后一个 1 指出了 1byte_offs_flag 值为 1 ,即每个偏移量占用 1 个字节。第五个字节和第六个字节组成了 02 BF ,这是下一个(第二条)记录起点对应的偏移量(相对于页开始处)。
3 )现在我们来看第三条记录,“ Field Start Offsets ”中的 94 94 ,对应着字段 field2 以及 field3 94 对应的二进制为 1001 0100 ,最高位的 1 表示该字段为 NULL ,字节 01 0100 指的是下一个字段的偏移值: 14 。同时,我们可以看到, NULL 值并没有真正占用“ Field contents ”的空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值