假设您不知道leveldb数据库中的确切键。
我尝试在键范围内插入3个键并使用GetApproximateSizes,结果始终为零。
那么如何检查leveldb中是否有任何键?
答案 0 :(得分:1)
我们通过更高级别的API levelUP在NodeJS项目中使用leveldb。使用levelUP API,您可以请求所有密钥流,并设置limit=1
以将响应限制为最多一个密钥。如果数据库为空,您将获得一个空流,否则您将获得一个只包含一个项目的流。
var empty = true;
db.createReadStream(db, {
keys: true,
values: false,
limit: 1
}.on('data', function(data) {
empty = false;
}.on('end', function() {
console.log('db is ' + (empty ? 'empty' : 'not empty'));
});
我们在npm模块level-is-empty中使用此技术。
由于您需要使用leveldb本机API的解决方案,因此我研究了levelUP如何实现createReadStream()
API。
在levelUP中,createReadStream is implemented using an iterator。
在levelDOWN中,创建了本机Iterator实例here。 Calling next
on it tells you whether the iterator has more data or is finished
我找到了一个如何使用原生leveldb迭代器here
的示例显然,迭代器方法Valid()
告诉您是否有更多的键要读取。因此,通过简单地调用SeekToFirst(),然后调用Valid(),您应该能够找出数据库中是否存在任何键。
这是我最好的猜测(代码未经测试,我手边没有C编译器)
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
it->SeekToFirst();
bool isEmpty = !(it->Valid());
delete it;
答案 1 :(得分:0)
您不能只使用leveldb扫描并打印所有键和值。例如,要打印数据库中的所有键和值,您可以执行以下操作:
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {
cout << it->key().ToString() << ": " << it->value().ToString() << endl;
}
assert(it->status().ok()); // Check for any errors found during the scan
delete it;
现在GetApproximateSizes给出零值,因为你刚刚插入了3个键,它们仍然在内存中(可记忆)并且还没有到达文件系统。一旦memtable满了(默认为4MB),它就会在0级创建第一个文件。因此,它对更大的数据库和更大的键范围更有用。
在你的情况下,文件系统中唯一存在数据的地方是重做日志,如果你的键是字符串,你可以通过在db目录中调用'strings logfile'(在linux中)来打印字符串来快速检查部分密钥是确认数据进入的快速方法。