28 我们每一行的实际数据在磁盘上是如何存储的?
2023/2/27大约 3 分钟
一行数据在磁盘文件里存储格式
变长字段的长度列表 null值列表 数据头 真实数据值
有一行数据是 “jack NULL m NULL xx_school”,那么他真实存储大致如下所示:
0x09 0x04 00000101 0000000000000000000010000000000000011001 jack m xx_school
刚开始先是他的变长字段的长度(注意是倒序),用十六进制来存储,然后是NULL值列表(倒序),指出了谁是NULL,接着是40个bit位的数据头,然后是真实的数据值,就放在后面。
在读取这个数据的时候,
- 他会根据变长字段的长度,先读取出来jack这个值,因为他的长度是4,就读取4个长度的数据,jack就出来了;
- 然后发现第二个字段是NULL,就不用读取了;
- 第三个字段是定长字段,直接读取1个字符就可以了,就是m这个值;
- 第四个字段是NULL,不用读取了;
- 第五个字段是变长字段长度是9,读取出来xx_school就可以了。
但是等等,大家觉得真正在磁盘上存储的时候,我们那些字符串就是直接这么存储在磁盘上吗?显然不是的!
实际上字符串这些东西都是根据我们数据库指定的字符集编码,进行编码之后再存储的,所以大致看起来一行数据是如下所示的:
0x09 0x04 00000101 0000000000000000000010000000000000011001 616161 636320 6262626262
我们的字符串和其他类型的数值最终都会根据字符集编码,搞成一些数字和符号存储在磁盘上。
一行数据在磁盘上的物理存储结构
那么我们今天来给大家简单提一下,在实际存储一行数据的时候,会在他的真实数据部分,加入一些 隐藏字段,这个隐藏字段跟后续的一些内容是有关联的,大家先了解一下。
首先有一个 DB_ROW_ID 字段,这就是一个行的唯一标识,是他数据库内部给你搞的一个标识,不是你的主键ID字段。如果我们没有指定主键和 unique key 唯一索引的时候,他就内部自动加一个ROW_ID作为主键。
接着是一个 DB_TRX_ID 字段,这是跟事务相关的,他是说这是哪个事务更新的数据,这是事务ID。后续再提。
最后是 DB_ROLL_PTR 字段,这是回滚指针,是用来进行事务回滚的,后续在讲解事务的时候再详细说。
所以如果你加上这几个隐藏字段之后,实际一行数据可能看起来如下所示:
0x09 0x04 00000101 0000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262
上面几个隐藏字段都加了括号说明了,上面那基本就是最终在磁盘上一行数据存储格式。