Python 创建可增量更新的高效基于文件的索引

Python 创建可增量更新的高效基于文件的索引,python,mongodb,dictionary,indexing,persistence,Python,Mongodb,Dictionary,Indexing,Persistence,作为一个研究项目,我目前正在用Python从头开始编写一个面向文档的数据库。与MongoDB一样,数据库支持在任意文档键上创建索引。这些索引目前使用两个简单的字典实现:第一个字典包含索引字段的键(可能是散列的)值,以及与该字段值关联的所有文档的存储键的值,这允许DB在磁盘上定位文档。第二个字典包含与之相反的内容,即作为给定文档的存储键,作为索引字段的(散列)值(这使得从索引中删除文档更有效)。例如: doc1 = {'foo' : 'bar'} # store-key : doc1 doc2 =

作为一个研究项目,我目前正在用Python从头开始编写一个面向文档的数据库。与MongoDB一样,数据库支持在任意文档键上创建索引。这些索引目前使用两个简单的字典实现:第一个字典包含索引字段的键(可能是散列的)值,以及与该字段值关联的所有文档的存储键的值,这允许DB在磁盘上定位文档。第二个字典包含与之相反的内容,即作为给定文档的存储键,作为索引字段的(散列)值(这使得从索引中删除文档更有效)。例如:

doc1 = {'foo' : 'bar'} # store-key : doc1
doc2 = {'foo' : 'baz'} # store-key : doc2
doc3 = {'foo' : 'bar'} # store-key : doc3
对于
foo
字段,这些文档的索引字典如下所示:

foo_index = {'bar' : ['doc1','doc3'],'baz' : ['doc2']}
foo_reverse_index = {'doc1' : ['bar'],'doc2' : ['baz'], 'doc3' : ['bar']}
(请注意,反向索引也包括值列表[而不是单个值],以适应列表字段的索引,在这种情况下,列表字段的每个元素将分别包含在索引中)

在正常操作期间,索引驻留在内存中,并在每次插入/更新/删除操作后实时更新。为了持久化它,它被序列化(例如作为JSON对象)并存储到磁盘,这对于索引大小高达100k的条目来说相当有效。但是,随着数据库大小的增长,程序启动时的索引加载时间变得有问题,并且由于写入索引会产生很大的开销,因此将更改实时提交到磁盘几乎是不可能的


因此,我正在寻找一种持久性索引的实现,它允许高效的增量更新,或者,以不同的方式表示,在将索引持久化到磁盘时,不需要重写整个索引。解决这个问题的合适策略是什么?我曾考虑使用链表实现一个可寻址的存储空间,对象可以写入其中,但我不确定这是否是正确的方法。

我的建议仅限于更新持久性索引;程序启动时的额外时间不是一个主要的时间,也不能真正避免

一种方法是为索引使用预先分配的磁盘空间(可能也用于其他集合)。在预分配中,定义与索引的每个条目相关联的经验大小以及磁盘上索引的总大小。例如,索引的每个条目有1024个字节,总共有1000个条目。 该策略允许直接访问磁盘上索引的每个条目。您只需将位置与索引一起存储在内存中。每当您在内存中更新索引项时,都会直接指向它在磁盘上的确切位置,并只重写一个项

如果第一个索引文件已满,只需创建第二个文件;始终为磁盘上的文件预先分配空间(1024*1000字节)。您还应该为其他数据预先分配空间,并选择使用多个固定大小的文件,而不是单个大文件

如果索引的某些条目需要超过1024字节,只需为较大的条目创建一个额外的索引文件;例如,每个条目2048字节,总共100个条目。 最重要的是使用固定大小的索引项进行直接访问


我希望这能有所帮助

谢谢你的回答,这肯定指向了正确的方向,也符合我对他的问题的看法。目前,我正在阅读SQLite源代码,看看它们是如何解决这个问题的。你知道关于这个主题的更多具体资源吗?我不知道关于这个主题的任何具体资源。如果您知道任何发布内部文档的数据库提供商,我认为这是一个开始。如果答案足够好,不要忘记接受它。