我搜索了支持整数键和整数值的键值存储。LevelDB 似乎是一个不错的选择,但我找不到任何关于是否支持整数值/键的信息
4 回答
你可以在 LevelDB 中存储几乎任何东西。您通过该Slice
结构将不透明的数据切片提供给 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 中存储整数(作为键和值)通常很好,但它们将通过 排序,BytewiseComparator
因此您的键必须支持字节比较。这也意味着,如果您依赖键的特定顺序,那么您必须注意系统上的字节序。
您还可以通过接口编写自己的比较器,Comparator
这将允许您替换默认值BytewiseComparator
。
在许多情况下,更精细的整数键编码方案是更好的选择。将 int 打包到 char* 中的双补码表示中(如该问题的另一个答案中所建议的)是一种选择;varint 编码是另一种(为小整数节省空间,可以存储任意数字而没有上限)。
为了扩大 Link 的答案,部分原因是我刚刚在我正在写的这本书中一直在玩这个确切的东西,你可以在下面看到他/她谈到的 BytewiseComparator 结果。
另一种方法是将二进制整数翻转为大端格式,以便它们可以使用默认比较器进行排序。这使得组合键更容易。
long flippedI = htonl(i);
请注意,LevelDB 非常快。我已经在 iPhone4 上进行了测试,它有 50,000 个带有辅助键的文本键控记录,因此大约有 100,000 个键/值对,并且它一直在尖叫。
编写一个自定义比较器非常容易,它永远被您的数据库使用,并且仍然使用 ByteWiseComparator 作为您的数字以外的键。最大的问题是决定您的自定义规则是否涵盖了哪些键。
一种简单的方法是说所有非整数键的长度都超过 4 个字符,因此您假设 4 字节键是整数。这意味着您只需要确保添加尾随空格或其他东西来推动它。这一切都非常随意,取决于您,但请记住您拥有的仅有的两条信息是关键内容及其长度。给定键没有其他元数据。
使用具有标准 BytewiseComparator 的数据库的标准比较器样本的部分结果,int 键从 1 开始并上升 1 到 1000
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 明确支持整数键(和值,如果您使用已排序的重复项)。http://symas.com/mdb
当为整数键配置数据库时,键比较函数也快得多,因为它们可以一次比较一个字,而不是像默认的面向字符串的比较那样一次一次地比较字节。
免责声明:我是 LMDB 的作者。当然,这并没有使事实有任何不同。