



通常,在设计一种文件格式时,首先要确定寻址方式:是否要将文件拆分为相同大小的页、哪些页由单个块或多个连续块所组成。大多数原地更新的存储结构都使用相同大小的页,从而大大简化了读取和写入访问。仅追加(append-only)的存储结构通常也按页写入数据:记录被一条一条地追加上去,一旦内存中该页写满了,就将其刷写到磁盘上。
文件通常以定长的头部(header)开始,可能以一个定长的尾部(trailer)结束。尾部包含需要被快速访问的辅助信息或解析文件其余部分所必要的信息。文件的其余部分被分成多个页,图3-3展示了文件的大致组织方式。
图3-3:文件组织方式
许多数据库的表结构(schema)是固定的,其指定了表中字段的数量、顺序和类型。固定的表结构有助于减少磁盘上存储的数据量:只需使用位置标识符而不用让每条记录都带上字段名。
假如我们要为公司名册设计一个格式,以保存每个员工的姓名、生日、税号和性别,则有几种方案可以选用。我们可以将定长字段放在结构体头部,接着是变长字段:
定长字段: | (4字节) employee_id | | (4字节) tax_number | | (3字节) date | | (1字节) gender | | (2字节) first_name_length | | (2字节) last_name_length | 变长字段: | (first_name_length字节) first_name | | (last_name_length字节) last_name |
现在,若要访问first_name,则我们可以在定长区域之后切片出first_name_length个字节。若要访问last_name,则我们首先要算出在此之前的所有变长字段的总长度,以找到last_name的起始位置。为了避免涉及多个字段的计算,我们可以将偏移量和长度都编入定长区域,这样就可以独立地定位任何一个变长字段。
构建更复杂的结构常常会涉及层次结构:原始类型构成字段,一组字段构成单元,多个单元组成页,页组成段,段组成区域,等等。没有必须遵守的严格规则,一切都取决于你要为怎样的数据创建格式。
数据库文件通常由多个部分组成,并且在该文件的头部、尾部或另一个单独的文件中包含一个查找表,记录了这些部分的起始偏移量。