在 leveldb 上按值查找

Posted

技术标签:

【中文标题】在 leveldb 上按值查找【英文标题】:Find by value on leveldb 【发布时间】:2018-01-16 16:12:40 【问题描述】:

我一直在使用 leveldb,它非常擅长它的设计用途——根据键存储和获取键/值对。

但现在我想做一些更高级的事情,却发现自己立即卡住了。有没有办法按值查找记录?我能想到的唯一方法是遍历整个数据库,直到找到具有我正在寻找的值的条目。如果我要查找具有该值的多个条目(基本上是“where”查询),情况会变得更糟,因为每次尝试执行此类查询时我都必须遍历整个数据库。

我是否正在尝试做 Leveldb 不适合做的事情,我应该改用另一个数据库吗?或者有什么好的方法可以做到这一点?

【问题讨论】:

您使用什么库与 leveldb 交互?也许我可以更新我对直接 javascript API 的回答。 FWIW,wiredtiger 使使用键值存储更容易source.wiredtiger.com/3.0.0/schema.html 【参考方案1】:

你是对的。基本上你需要知道的是key composition

其次,您不要在 SQL WHERE 子句中按值本身进行查询,而是使用像 age = 42 这样的布尔查询。

要回答您的特定问题,假设您在 leveldb 中有第一个键值命名空间,您将对象存储在其中,例如,值在 json 中序列化:

 key                    |          value
-------------------------------------------------
 namespace |    uid     |          value
================================================
 users     |    1       | name:"amz", age=32
------------------------------------------------
 users     |    2       | name:"abki", age=42

在另一个命名空间中,您按年龄索引用户 uid:

         key              | value
----------------------------------
 namespace    | age | uid | value
==================================
 users-by-uid |  32 | 1   | empty
----------------------------------
 users-by-uid |  42 | 2   | empty

这里的值是空的,因为键必须是唯一的。我们可以认为给定行的值是 uid 它组成的列 到键中,使每一行的键唯一。

在第二个命名空间中,(user-by-uid, 32) 开头的每个键都匹配回答查询age = 32 的记录。

【讨论】:

我不确定我是否理解正确,但这是否意味着我必须为进行此类查询所需的所有条目创建反向索引? 是的。你必须 知道了,还有一个简单的问题。这是使用 LevelDB 时的常见做法吗?还是您只是建议一种可以解决此问题的解决方案。我想我很好奇我是否试图将 LevelDB 用于错误的目的,并且它不应该以这种方式使用(我应该使用另一种类型的 DB)。 好吧,leveldb 是低级的,键组合是必须付诸实践的模式,以便在键/值范式之上开发高级模式 我举了一个例子,使用键组合将多个表存储在单个 kv 中(通过命名空间)并按属性(也称为二级索引)索引值。所有这些都是关键组合的一个实例。

以上是关于在 leveldb 上按值查找的主要内容,如果未能解决你的问题,请参考以下文章

LevelDB 源码剖析MemTable模块:SkipListMemTable持久化

LevelDB 源码剖析MemTable模块:SkipListMemTable持久化

LevelDB 源码剖析MemTable模块:SkipListMemTable持久化

[leveldb] Compaction

leveldb学习:skiplist

leveldb学习:sstable