我有一堆处理文档群集的代码。一步涉及计算每个文档与给定语料库中的每个其他文档的相似性(对于“类似”的一些不重要的定义),并存储相似性以供以后使用。相似之处是不同的,我不关心具体的相似性是什么,我的分析的目的,只是它在什么桶。例如,如果文件15378和3278是52%相似,有序对(3278,15378)得到存储在[0.5,0.6]桶中。在初始分析之后,文档有时会在语料库中添加或删除,因此根据需要可以在桶中添加或删除相应的对。
我正在研究存储这些ID对列表的策略。我们发现一个SQL数据库(这个项目的大多数其他数据都存在)对于我们的目的而言太慢而且磁盘空间太大,所以目前我们将每个存储桶存储为磁盘上的整数压缩列表(最初zlib压缩,但现在使用lz4代替速度)。我喜欢这件事:
那种糟糕的事情:
那么:我应该关注哪种数据结构?我怀疑正确的答案是某种奇特的简洁数据结构,但这不是我所熟知的空间。另外,如果重要的是:所有文档ID都是无符号的32位整数,处理这些数据的当前代码是用C语言编写的,作为Python扩展,所以这可能是我们坚持的通用技术系列。
答案 0 :(得分:1)
如何在每个桶中使用一个哈希表或B树?
磁盘哈希表是标准配置。也许BerkeleyDB库(可用于库存python)将为您服务;但要注意他们,因为他们来自交易,他们可能会很慢,可能需要一些调整。有很多选择:gdbm,tdb,你们都应该尝试一下。只需确保检查API并使用适当的大小初始化它们。有些不会自动调整大小,如果你给它们提供太多数据,它们的性能就会下降很多。
无论如何,如果你有很多变化,你可能想要使用更低级别的东西而不进行交易。
一对整数很长 - 大多数数据库应该接受一个长的密钥;事实上,许多人会接受任意字节序列作为键。
答案 1 :(得分:1)
为什么不直接存储一个包含自上次重写以来被删除的内容的表?
此表可以与您的主存储桶结构相同,也可以使用Bloom过滤器进行快速成员资格检查。
您可以在没有删除项目的情况下重新编写主存储桶数据,或者当您要重新编写它以进行其他修改时,或者已删除项目:存储区大小的比率超过时一些门槛。
此方案可以通过在每个存储桶旁边存储每个已删除的对,或者为所有已删除的文档存储单个表来实现:我不确定哪个更适合您的要求。
保留单个表,很难知道何时可以删除项目,除非您知道它会影响多少个桶,而只需在删除表太大时重写所有存储桶。这可行,但它有点停止世界。
您还需要对流式传输的每对进行两次检查(例如,对于(3278, 15378)
,您需要检查3278
或15378
是否已被删除,而不仅仅是检查对(3278, 15378)
是否已被删除。
相反,每个已删除对的每个桶表需要更长时间才能构建,但检查时要快一些,并且在重写存储桶时更容易崩溃。
答案 2 :(得分:-1)
您正在尝试重新发明新时代NoSQL数据存储中已存在的内容。 根据您的要求,有2个非常好的候选人。
两者都支持数据结构,如字典,列表,队列。像追加,修改或删除这样的操作也可用,并且非常快。
它们的性能都是由可以驻留在RAM中的数据量驱动的。 由于您的大多数数据都是基于整数的,因此不应该是一个问题。
我的个人建议是使用Redis,具有良好的持久性配置(即数据应定期从RAM保存到磁盘)。
以下是redis数据结构的简介: http://redis.io/topics/data-types-intro
redis数据库是一个轻量级安装,客户端在Python中可用。