使用键值数据库作为具有持久索引的集合

时间:2012-12-17 22:35:30

标签: indexing key-value openldap leveldb kyotocabinet

由于下面有点长:这是tl; dr; version:快速键值查找是否存在现有的键/值最佳实践,类似于具有持久索引的基于哈希的集合?

我对键值数据库的世界感兴趣,到目前为止还未能弄清楚如何有效地实现以下用例:

假设我们想要序列化一些数据,并通过持久的唯一整数索引在其他地方引用它们。例如:Key = unsigned int,Value = MyData。

数据库应具有快速键查找功能,并确保MyData是唯一的。

现在,当我向数据库插入一个新值时,我可以为它分配一个新的索引键,例如当前数据库的大小或为了防止在删除项目后发生冲突,我可以在外部保留一些计数器。

但是,我如何确保不将相同的MyData值插入数据库?到目前为止,它看起来好像这对于键值数据库来说无法有效实现 - 这是正确的吗?即我想要迭代整个数据库只是为了确保MyData值不在那里......

那么实施这个的最佳实践是什么呢?

对于背景:我在KDevelop上工作,我们使用上面的代码分析缓存。我们实际上有一个上述用例1的自定义实现。如果您对内部感兴趣,请搜索Bucket和ItemRepository,并查看2以了解ItemRepository的示例用法。

但你可能会同意,这段代码很难理解,因而难以维护。我想将其性能与可能导致更简单代码的替代解决方案进行比较 - 但前提是它不会导致严重的性能损失。考虑到关于OpenLDAP MDB,Kyoto Cabinet和LevelDB等键值存储性能的炒作,这是我想要开始的地方。

我们在KDevelop中所拥有的 - 据我所知 - 基本上是一种混合磁盘/内存中的哈希映射,它会定期保存到磁盘上(当然,这会导致主要数据损坏)崩溃等)。项目基于它们的散列值存储在一个位置,当然,只要散列函数很快,它们也允许相对快速的值查找。增加的扭曲是您还可以获得某种持久性数据库索引,可用于非常有效地查找项目。

所以 - 长话短说 - 如何用关键/价值数据库如LevelDB,Kyoto Cabinet,OpenLDAP MDB来做到这一点 - 你说出来了吗?

3 个答案:

答案 0 :(得分:3)

除非我在这里遗漏了一些东西 - 通常你的哈希算法是一致的,并且会为相同的数据提供相同的密钥。因此,您只需要查找密钥以查看密钥是否已存在,或者处理数据库给您的(可能是重复的密钥)错误。

afaik Key / Value DB可以并将为您强制执行唯一的Value约束,即如果您尝试保存已存在的值,则会收到错误。

答案 1 :(得分:3)

听起来你想要做OpenLDAP对其Equality指数的处理。也许这与OrientDB示例相同,我没有读过它。

主表由单调递增的整数键(称为entryID)索引,并存储数据值。等式索引由值的散列索引,并存储与散列匹配的entryID列表。由于哈希可能有冲突,因此在等式索引中只存在一个条目并不能证明唯一性或重复。您仍然需要检查实际值。

如果您使用MDB,BDB或其他支持重复键的数据库,则更快/更简单的方法是使用哈希作为键来保留一个表。在MDB和BDB中都有一个GET_BOTH请求,它匹配密钥和数据以执行提取。如果成功,那么您肯定知道该值已存在。否则,它允许您保存任何数据值,而不用担心是否存在哈希冲突。

请注意,在MDB中使用重复键,值的大小限制为不到磁盘页面的一半。

答案 2 :(得分:0)

你的价值观有多大?

我只是将它们存储在密钥中,让数据库完成所有工作。

适用于大多数KV商店的典型LevelDB样式是使用一对键,前缀表示类型

例如:

Key = 'i' + ID 
Value = valueString

Key = 'v' + valueString
Value = ID

在需要允许多个相同valueStrings的系统中,您可以将ID移动到第二个键的尾部

Key = 'v' + valueString + ID
Value = empty