想象一下应该由我的程序编辑的大文件。为了增加读取时间,我使用mmap(),然后只读出我查看的部分。但是,如果我想在文件中间添加一行,那么最好的方法是什么?
是添加一行然后移动文件其余部分的唯一方法吗?这听起来很贵。
所以我的问题基本上是:在一个巨大的文件中添加数据的最有效方法是什么?
此问题先前在此处提出: How to edit a big file
答案建议使用sqlite3而不是直接文件。这让我很好奇,sqlite3如何解决这个问题?
答案 0 :(得分:1)
SQLite是一个关系数据库。它的主要编辑手段是btree表和btree索引。即使记录增长,BTrees也可以进行编辑。此外,SQLite使用.journal
文件在保存文件时从崩溃中恢复。
BTrees只通过其主键或任何索引列为任何记录支付日志(N)查找时间(这比排序记录要快得多,因为日志库很大)。因为BTrees几乎在所有地方使用块指针,所以可以相对轻松地更新有序列表的中间位置。
RichN指出,SQLite会在文件中浪费空间。定期运行VACUUM
以释放它。
顺便说一句,我手写了BTrees。如果你出于某种原因必须写作,那么写作是一种痛苦但值得的。
答案 1 :(得分:0)
SQLite数据库文件的内容由记录和数据结构组成,以访问这些记录。 SQLite跟踪文件的已使用部分以及未使用的部分(在删除记录时可用。)当您添加新记录并且它适合未使用的段时,它将成为其位置。否则它将附加到文件中。更新任何索引以指向新数据。更新索引可能会附加更多索引记录。 SQLite(以及一般的数据库管理器)在插入新记录时不会移动任何内容。
请注意,随着时间的推移,内容会分散在磁盘上。顺序记录不会彼此靠近,这可能会影响某些查询的性能。
SQLite VACUUM
命令可以删除文件中未使用的空间,以及修复数据中的位置问题。见VACUUM Command