在我正在创建的数据库中,我很好奇为什么大小比内容大得多,并检查了十六进制代码。在一个4 kB的文件中(单行作为测试),有两个主要的块,大约900和1000字节,还有一些较小的块,都是空字节0x0
我想不出有任何合理的理由存储数千个空字节,这会大大增加数据库的大小。
有人可以向我解释一下吗?我试过搜索,却找不到任何东西。
答案 0 :(得分:3)
本页描述了SQLite数据库文件(`* .sqlite)的结构:
https://www.sqlite.org/fileformat.html
SQLite文件被分区为“页面”,长度在512到65536之间 - 在您的情况下,我认为页面大小可能是1KiB。如果您存储的数据小于1KiB(就像您在单个测试行中一样,我想这可能是100字节长?)那么剩下900字节 - 未使用(解除分配)的空间通常在之前被清零(然后使用。
它与计算机工作内存(RAM)的工作方式相同 - 因为RAM也使用分页。
我想你期望文件非常紧凑,内部表示简洁;这个 是一些文件格式的情况 - 例如老式的基于OLE的Office文档,但其他(尤其是数据库文件)需要不同的文件布局,这些文件布局同时进行优化,以便快速访问,快速插入新数据,也被安排来帮助防止内部碎片 - 这是以一些浪费的空间为代价的。
快速思考实验将证明为什么可变(即非只读)数据库不能使用紧凑的内部文件结构:
INSERT
新行。DELETE
现有行。请注意,您无法通过“移动”数据来实际“删除”空间(例如在记事本中使用 Backspace 键)因为这意味着复制文件中的所有数据 - 这在很大程度上是一个坏主意UPDATE
行,如果没有,则在末尾添加一个新行,覆盖现有行(a-la INSERT
然后DELETE
)*.sqlite
文件中,创建“子文件”,它具有已知的固定大小(例如4KiB),只存储单个表的行,直到子文件已满;它们还将指针(如链接列表)存储到包含其余数据的下一个子文件(如果有)。然后,您只需创建新的子文件,因为您需要在文件中有更多空间并设置其下一个文件指针。这些子文件是数据库文件中的“页面”,以及如何在同一父文件系统文件中包含多个读/写数据库表。然后除了存储表数据的这些页面之外,还需要存储索引(这使得您可以在不需要扫描整个表或文件的情况下立即找到表行)和其他元数据,例如作为列定义本身 - 通常它们也存储在页面中。关系(表格)数据库文件本身可以被视为文件系统(只是封装在父文件系统中......可以在*.vhd
文件中......可以隐藏在varbinary
数据库中列...在另一个文件系统中),甚至数据库系统本身也已经与操作系统进行了比较(因为它们提供了运行程序(存储过程)的环境,它们提供IO服务等等 - 如果它们几乎是循环的,你看一下20世纪70年代的旧的基于COBOL的大型机,当时你的所有IO操作都只限于计算机记录管理操作(插入,更新,删除)。