Skip to content

Latest commit

 

History

History
69 lines (39 loc) · 4.3 KB

4.block-record-organization.md

File metadata and controls

69 lines (39 loc) · 4.3 KB

2.3 块与记录组织

概念介绍

  • 记录

    按照若干个字段元素组成的数据集合。

  • 数据块

    由多个数据记录元素组成的一个数据集合,在物理上对应的是一块连续的存储空间。

总结而言,块中有若干行记录,每行记录中有若干个字段。

比如如下所示的 SQL 建表语句,按照 name,salary,address,gender,birthdate 的字段建立一个关系表。如果使用行存储的数据库,那么记录就是指数据库中的一行内容。

CREATE  TABLE MovieStar(
    name CHAR(30) PRIMARY KEY,
    salary INTEGER,
    address VARCHAR(255),
    gender CHAR(1),
    birthdate DATE
);

记录的类型

  • 定长类型

    数据字段的长度固定,例如 int、short、date 等。

  • 变长类型

    数据字段的长度非固定,例如 varchar、blob、text 等。

记录的存储结构

了解了字段类型、记录以及块的定义之后,我们来看看一条记录是如何保存的,假设我们运行在 32 位的操作系统上,数据是按照 4 字节对齐存储的,因此数据库在存储定长数据时,也是按照对齐之后的数据进行存储的。

img

如上图所示,可以看到对齐之后的存储实际占用长度要比对齐之前的多一点,这个是可以接受的,字节对齐对 CPU 进行内存访问时是友好的,感兴趣的同学可以自行了解字节对齐的介绍。

下面我们针对概念介绍中提到的 SQL 结构的数据进行存储示例:

img

例如一条完整的记录里,通常除了存储具体的记录字段之外,还会额外存储这条记录的元数据信息,并且会把这些元数据信息放到记录最开始的位置,这部分内容称为记录的 header。

header 中存放的元数据信息主要有变长字段的偏移、字段的长度、记录最后修改的时间戳等(不同场景的记录需要存储的元数据可能是不一样的)。header 之后是具体每个字段的内容,这些内容一般叫做 data,data 中的内容会按照表结构的定义进行编排,因此一条完整的记录是按照 header + data 来存储的。

块的存储结构

块在存储中的组织与记录类似,可以简单地看成是由 header + data 数据组成,例如一个块要管理内部所有的记录,需要在块的 header 中保存每个记录的偏移、块最后修改的时间戳、块在存储结构中的位置信息等,因此 header 中的元数据主要是为了方便自身的管理和维护。

下面我们来看一个块里面是如何存放数据的,这里需要强调的是,块里面存储的地址偏移是相对于虚拟地址的偏移,并非实际物理磁盘的偏移。还需要注意,新插入的记录,是从块的末端往中间增长的,而未使用的空间是从 header 之后往块的末端增长的。

img

从图中可以看出记录 1 在最后,记录 4 在最前面,因为记录有可能不等长,无法事先根据记录的长度和块的总长来计算好能插入多少数据。

示例:假如一个块的大小是 100。

  • 如果记录都等长,都为 10,那么我们可以算出一个块最多能插入 10 条记录,并且可以从块的起始到末端的方向插入,最后刚好到 100 不会报错。

  • 如果记录不等长,事先也不知道这个块最多能容纳多少条记录的,如一条长度 10,一条长度 50 的记录,从起始往末端方向编排,如果下一条记录的长度为 50 ,因为不知道块中还有多少空间,也不会提前报错,那必然会插入失败。

    但是如果记录是从块的末端往前增长,那在插入 10 和 50 这两条记录后,由于长度为 50 的那条记录的偏移是 40(100 - 10 - 50 = 40),那就能知道当前的空间只剩 40 了,没办法容纳新的记录,然后提前报错然后重新分配块。