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

Indexing 将键值数据库用作具有持久索引的集合,indexing,key-value,openldap,leveldb,kyotocabinet,Indexing,Key Value,Openldap,Leveldb,Kyotocabinet,因为下面有点长:这是tl;博士版本:是否存在用于快速键和值查找的现有键/值最佳实践,例如具有持久索引的基于散列的集合 我对键值数据库的世界很感兴趣,到目前为止还没有弄清楚如何有效地实现以下用例: 假设我们想要序列化一些数据,并通过一个持久的、唯一的整数索引在其他地方引用它们。例如:Key=unsigned int,Value=MyData 数据库应具有快速键查找功能,并确保MyData是唯一的 现在,当我在数据库中插入一个新值时,我可以给它分配一个新的索引键,例如数据库的当前大小,或者为了防止删

因为下面有点长:这是tl;博士版本:是否存在用于快速键和值查找的现有键/值最佳实践,例如具有持久索引的基于散列的集合

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

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

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

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

但如何确保不将相同的MyData值插入数据库?到目前为止,在我看来,对于键值数据库来说,这似乎是不可能的——这是正确的吗?也就是说,我不想只是为了确保MyData值不在其中而遍历整个数据库

那么,实现这一点的最佳实践是什么

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

但您可能会同意,这段代码很难理解,因此很难维护。我想将它的性能与可能导致代码更简单的替代解决方案进行比较——但前提是它不会招致严重的性能损失。考虑到围绕关键值存储(如OpenLDAP MDB、Kyoto Cabinet和LevelDB)性能的宣传,我想从这里开始

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


那么-长话短说-如果使用LevelDB、Kyoto Cabinet、OpenLDAP MDB等键/值数据库,您会如何做到这一点-您可以这么说吗?

除非我在这里遗漏了什么-通常您的哈希算法是一致的,并且将为相同的数据提供相同的键。因此,您只需查找密钥,查看它是否已经存在,或者处理DB返回给您的(可能是重复密钥)错误


afaik键/值DBs可以并且将为您强制一个唯一的值约束,即,如果您尝试保存一个已经存在的值,您将得到一个错误。

听起来您希望像OpenLDAP那样使用其相等索引。也许这与OrientDB示例相同,我没有读过

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

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


这里有一个警告,在使用重复键的MDB中,值的大小限制在磁盘页的一半以下。

值字符串有多大

我只需要将它们存储在一个密钥中,然后让数据库完成所有工作

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

例如:

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

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

是的,散列算法是一致的,但对于破坏您推理的任意值不是唯一的,不是吗?详细说明:对于要插入的任意值,您将使用什么作为键?对于给定的值,它必须是唯一的,并且查找速度相对较快(即,没有O(N)算法迭代所有值以找到合适的键)。然后可以使用非任意键。例如跟踪最大值的序列号,或类似“FirstKey”“SecondKey”“ImportAndAppKey”或类似的字符串描述符。。。正确的?如果使用序列号,甚至可以将“top”保存到数据库中-如果有100个“bucket”,DBNAME.top=100。或者类似的。下面是OrientDB的一个例子-也许您的NOSQL db可以自动生成索引,并使用这些索引来代替或添加任意键?@milianw,不,这并没有破坏推理:如果已经添加了另一个MyData,它将使用相同的键添加,这意味着您只需检查分配给现有键的值(如果该键已存在)并将旧值与新值进行比较,如果他们同意,则该值已存在OrientDB示例看起来非常有趣,但这正是我所寻找的。谢谢,这听起来正是我想要的。
Key = 'v' + valueString + ID
Value = empty