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