# 数据库文件格式 > `fumidb`的数据库文件扩展名一般为`.fdb`,不做强制要求 由于文件内普遍以uint64作为指针,因此理论最大支持文件大小为`16384PB`,在现有条件下完全足够使用。 ## 文件头 文件最开头填充了固定的8字节ascii编码`FUMIDB\1\0`。前6字节必须为`FUMIDB`,表明本文件为`fumidb`数据库文件格式。7, 8字节`\1\0`作为数据库的版本,是一个小端的uint16,在这里表示第1版,之后将依次递增。今后可能会在文件头增加更多字段,因此前`256`字节保留以备后用。 ``` 0 8 16 ┌───────────────────┬───────────────────┐ │ FUMIDB\1\0 │ ptr of unused blk │ ├───────────────────┼───────────────────┤ │ ptr of next table │ ...... ...... │ ├───────────────────┴───────────────────┤ │ possible other header data │ ├───────────────────────────────────────┤ │ possible other data (such as index) │ ├───────────────────────────────────────┤ │ some possible padding to fit 4k │ ├───────────────────┬───────────────────┤ │ ptr of next table │ first table head │ ├───────────────────┴───────────────────┤ │ ...... ...... ...... │ ├───────────────────────────────────────┤ │ some possible padding to fit 4k │ ├───────────────────────────────────────┤ │ data blocks ... │ └───────────────────────────────────────┘ ``` ### 空闲块 #### 链表格式 对于空闲块,其开头将有一个8字节指针指向下一块空闲块,没有则置0。第一块未被使用的空闲块的指针被记录在文在最开头的`ptr of unused blk`,同样,没有则置0。对于除了文件头之外的每个空闲块指针,在指针之后紧跟一个uint16的数字,指示了本块空闲块的长度(以字节为单位),该长度包括指针和数字。因此,能加入链表的空闲块最短应为10字节,小于这个长度的未被使用部分将不再使用。 #### 新建 空闲块不会被主动新建,而是源于分配时富余的部分以及删除后的剩余。 #### 合并 受限于记录长度的数字为uint16,一块未被使用的空闲空间大小最大为`65535`,实际使用时不使其超过`4096`。如果确有连续的超过`4096`字节的空闲,应当划分为多个块。`4096`字节的块应当是`4k`对齐的。 #### 使用 使用时优先从第一个块遍历,比较其大小以及页对齐是否符合要求。当使用后仍有剩余,对于小于10字节的块,直接舍弃不用;否则更新块大小与相关链表指针。 ### 表 #### 新建 在新建表时将计算表头大小,优先选取一块未被使用的足够大的`4k`对齐部分写入表头。当找不到时,在文件末尾附加表头(留出新的对齐)。接下来将上一个表头开头的`下一个表头的指针`指向新表头的开头,然后建立相应数据结构,填充表头字段。 #### 修改 一旦创建数据表,将不支持修改。可以先删除表再重新创建,但这样数据将会丢失。 #### 删除 根据表头遍历所有表项,回收空间到空闲块,然后再回收表头,更新表头链表的指针,完成删除。