文件格式

虽然 LiteDB 是一个单文件数据库,但是数据库包含很多不同类型的信息,如索引、集合、文档。要管理这些东西,LiteDB 实现了数据库页面的概念。页面是相同信息的一个块,大小为 4096 字节。在磁盘文件上,页面是最小的读/写操作单元。共有 6 种页面类型:

  • 头部页面: 包含数据库信息,像文件版本、数据文件大小和空闲列表页面,以及哪一个是数据库上的第一个页面 (PageID = 0)。
  • 集合页面: 每个集合使用一个页面保持所有集合信息,像名称、索引、指针和选项。所有集合通过双向链表彼此互相连接。
  • 索引页面: 用于保持索引节点。LiteDB 实现了跳跃列表索引,因此每个节点有一个键和指向其他索引节点的级别链接(levels link pointers to others index nodes,不是太明白)。
  • 数据页面: 数据页面包含数据块。每个数据块表示一个以 BSON 格式序列化的文档。如果文档比一个页面大,数据块使用一个链接指向一个扩展页面。
  • 扩展页面: 需要多于一个页面的大型文档,被序列化在多个扩展页面中。扩展页面双向链接创建出一个单独的数据段,它存储了文档。每个扩展页面只包含一个文档或文档的一个块。
  • 空页面: 当一个页面被排除后,它会变成一个空页面。空页面将会用于下一个页面请求 (用于任何种类的页面)。

每个页面都有一个自己的头部和内容。头部用于管理公共数据结构,像页面标识、页面类型、剩余空间。每一个页面类型对内容的实现是不同的。

页面剩余空间

索引页面和数据页面包含一个元素集合 (索引节点和数据块)。这些页面可以存储数据并保持可用空间以存储更多。要在每个页面类型上保持空闲空间, LiteDB 实现了空闲列表节点。

空闲列表是一个双向链表,按可用空间排序。当数据库需要一个页面来存储数据时,它使用这个列表来搜索第一个可用的页面。然后,PagerService 修复页面顺序,或者,如果页面上没有更多空间的话,从空闲列表中移除它。

要使相似的数据关联起来,每个集合包含一个数据空闲列表。因此,在一个数据页面,所有数据块来自于同一个集合。索引也是一样。每个索引 (在每个集合上) 包含自己的空闲列表。这个方案消耗更多的磁盘空间,但是读/写操作会快得多。因为数据是关联的,并且一个挨个一个。如果你获取一个集合中的所有文档,数据库需要在磁盘上读的页面更少。

限制

  • 集合名称:
    • 模式:A-Z, _-, 0-9
    • 最大长度 60 字符
    • 大小写不敏感
  • 索引名称:
    • 模式:A-Z, _-, 0-9 (. 用于嵌套文档)
    • 最大长度 60 字符
    • 大小写敏感
  • BsonDocument 键名称:
    • A-Z, _-, 0-9
    • 大小写敏感
  • FileStorage 文件标识:
    • 模式:与文件系统路径/文件用法相同。
    • 大小写敏感
  • 集合: 所有集合名称 3000 字节 (常规情况下,每个集合有 8 字节)
  • 每个集合中的文档数:UInt.MaxValue
  • FileStorage 文件大小上限:每个文件 2 Gb
  • 索引键大小上限:序列化为 BSON 后 512 字节
  • BSON 文档大小:没有限制 (但是强烈推荐越小越好,最好在 200 kb 以下)
  • BSON 文档嵌套深度:20
  • 页面大小:4096 字节
  • 数据页面保留字节数:2039 字节 (像 PCT FREE)
  • 索引页面保留字节数:100 字节 (像 PCT FREE)
  • 数据库大小上限:理论上,UInt.MaxValue * PageSize (4096) = 16TB ~ 太大了!