文件格式
虽然 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 ~ 太大了!