Database 整型键/值能否存储在LevelDB中?

Database 整型键/值能否存储在LevelDB中?,database,key-value,leveldb,Database,Key Value,Leveldb,我搜索了支持整型键和整型值的键值存储。LevelDB似乎是一个不错的选择,尽管我找不到关于是否支持整数值/键的任何信息您可以在LevelDB中存储几乎任何东西。您可以通过结构将不透明的数据片段提供给LevelDB。以下是一个例子: int intKey = 256; int intValue = 256*256; Slice key((char*)&intKey, sizeof(int)); Slice value((char*)&intValue, sizeof(int));

我搜索了支持整型键和整型值的键值存储。LevelDB似乎是一个不错的选择,尽管我找不到关于是否支持整数值/键的任何信息

您可以在LevelDB中存储几乎任何东西。您可以通过结构将不透明的数据片段提供给LevelDB。以下是一个例子:

int intKey = 256;
int intValue = 256*256;

Slice key((char*)&intKey, sizeof(int));
Slice value((char*)&intValue, sizeof(int));

db->Put(leveldb::WriteOptions(), key, value);
差不多就是这样

但是,需要注意的一点是,虽然在LevelDB中存储整数(作为键和值)通常是可以的,但它们将通过
字节比较器
排序,因此您的键必须支持字节比较。这也意味着,如果您依赖于键的特定顺序,那么您必须注意系统上的endian属性


您还可以通过接口编写自己的比较器,该接口将允许您替换默认的
字节比较器

。在许多情况下,更精细的整数键编码方案是更好的选择。将int封装到char*中的两个补码表示中(如对该问题的另一个回答中所建议的)是一种选择;varint编码是另一种(为小整数节省空间,可以存储任意数字而无上限)。

要放大Link的答案,部分原因是我刚刚在我写的书中玩过这个东西,你可以看到他/她在下面谈到的BytewiseComparator结果

另一种方法是将二进制整数翻转为big-endian格式,这样它们就可以使用默认的比较器进行排序。这使得合成关键点更容易。
long flipedi=htonl(i)

请注意,LevelDB非常快。我在iPhone4上做过测试,有50000条带有辅助键的文本键记录,所以大约有100000个键/值对,它会尖叫起来

编写一个定制的比较器是非常容易的,它被数据库永远使用,并且仍然使用字节比较器来处理数字以外的键。最大的问题是确定自定义规则是否涵盖了哪些密钥

一种简单的方法是,所有非整数键的长度都超过4个字符,因此假设一个4字节的键是整数。这意味着您只需要确保添加尾随空格或其他东西来推动它。这一切都是非常随意的,取决于你,但请记住,你仅有的两条信息是关键内容及其长度。给定密钥没有其他元数据

使用带有标准BytewiseComparator的数据库,标准comparator的int键从1开始,递增1到1000,其中一部分结果来自标准comparator的示例

Listing the keys in decimal and hex
 256 ( 100)
 512 ( 200)
 768 ( 300)
   1 (   1)
 257 ( 101)
 513 ( 201)
 769 ( 301)
   2 (   2)
 258 ( 102)
 514 ( 202)
 770 ( 302)
   3 (   3)
 259 ( 103)
 515 ( 203)
 771 ( 303)
...
 254 (  fe)
 510 ( 1fe)
 766 ( 2fe)
 255 (  ff)
 511 ( 1ff)
 767 ( 2ff)

LMDB明确支持整数键(和值,如果您使用的是排序重复项)

当为整数键配置DB时,键比较函数也会更快,因为它们可以一次一个字地比较,而不是像默认的面向字符串的比较那样一次一个字节地比较


免责声明:我是LMDB的作者。当然,这并没有使事实有任何不同。

但是Get没有给我一个正确的切片?如果数据未填充“0”,它将如何工作?或者我在这里遗漏了什么?Get返回一个std::string,它可以包含任意字节数组。您还可以使用迭代器并使用它进行搜索,以便能够获得指向该值的切片,而无需任何复制。这是非常大的值的推荐方法。你的意思是翻转到大端顺序,而不是小端顺序。您在示例中使用了“htonl”,意思是“主机到网络”,网络字节顺序是big-endian。与其他较旧的数据库相比,LevelDB可能很快,但与LMDB相比,它相当慢。问题是关于LevelDB的。请停止向LMDB发布其他问题。问题上写着“我已经搜索了”,这意味着他仍在寻找选择。LevelDB是一个可证明的较差选项,而LMDB是一个可证明的较好选项。@hyc,这取决于您的需求。我刚刚查看了LMDB,发现它完全不合适,但LevelDB似乎正是我所需要的。当然,“取决于您的需求”是一个公平的说法。大多数使用数据库的人都要求“必须可靠地检索以前存储的数据”。它们还要求“必须以可预测的延迟存储数据”。LevelDB在这两方面都失败。因此,除非您正在编写另一个像MongoDB这样的有损数据存储,而您实际上并不关心如何检索数据,否则LevelDB通常不适合作为键值存储。透露您在LMDB开发中的角色是礼貌的,就像有人在搜索我的选项一样。varint不是两个补码方法的优化吗?不是。Variant(有多个变体)使用可变大小,而两个补码使用固定大小。这意味着变量在理论上是无界的(但在实际实现中不是),而两个补码的范围是-2^n到2^n-1。此外,变量需要对负数进行之字形编码,而补码2则为负数保留一个符号位。