InnoDB记录结构浅析
2007-12-12 14:54
274 查看
[align=center]InnoDB记录结构浅析[/align]
[align=center]译者:杨万富[/align]
InnoDB记录由三个部分组成,见表1:
表1:InnoDB的记录组织形式
备注:
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的组织形式
如果你仅仅打算读取该记录,那么标志位“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(字段内容)
这个部分用来存放记录的实际数据,按照定义的顺序进行存放。
4 举例
创建一张表:
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:
表3 物理存储中记录的组织形式
对记录进行重新编排,格式如下所示:
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”的空间。
[align=center]译者:杨万富[/align]
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 |
当给定记录的起点指针(即指向“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(字段内容)
这个部分用来存放记录的实际数据,按照定义的顺序进行存放。
4 举例
创建一张表:
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:
表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 | [align=left]..-..OOOOOOOOO..[/align] |
[align=left]0D4290: 15 13 0C 06 00 00 78 0D 02 BF 00 00 00 00 04 21[/align] | [align=left]......x........![/align] |
0D42A0: 00 00 00 00 09 2A 80 00 00 00 2D 00 84 50 50 50 | .....*....-..PPP |
[align=left]0D42B0: 50 50 50 16 15 14 13 0C 06 00 00 80 0D 02 E1 00[/align] | [align=left]PPP.............[/align] |
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 | [align=left]..QQQ...........[/align] |
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”的空间。
相关文章推荐
- InnoDB记录结构浅析
- InnoDB记录结构浅析(摘自老杨)
- 思考mysql内核之初级系列14---innodb的旧式记录结构
- 栈帧结构浅析记录
- Sql Server按树形结构排序查询表记录(CSDN论坛转载)
- 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁
- 20131030: 森林结构的运用(poj: 树的转换,电话号码,物质分解记录);带权并查集(食物链);C++输入;map的基本使用
- c++类结构记录
- MySQL ·InnoDB 文件系统之文件物理结构
- 记录我的数据结构(C语言)学习历程(2017年3月30号开始)
- 浅析Java虚拟机结构与机制
- mysql两种表存储结构myisam和innodb的性能比较测试
- SQL Server 存储(2/8):理解数据记录结构
- 关于重做记录的结构
- MySQL-InnoDB Compact 行记录格式
- 浅析JVM内存结构和6大区域
- 怎样快速获取innodb的表记录数
- DTS开发记录(1)--系统总体结构
- 浅析MVC设计思想与三层体系结构
- myisam、innodb物理结构