← 返回主页

leveldb 使用指南

leveldb 是 Google 开发的一个高性能、轻量级的嵌入式键值存储库,提供了快速的随机读写操作和高效的压缩。它被广泛应用于 Chrome 浏览器、LevelDB 等项目中。

📦 安装

Ubuntu/Debian

sudo apt-get install libleveldb-dev

从 GitHub 编译

git clone https://github.com/google/leveldb.git
cd leveldb
mkdir build && cd build
cmake ..
cmake --build .
sudo make install

🚀 基础使用

打开/创建数据库

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    // 打开或创建数据库
    leveldb::Status status = leveldb::DB::Open(options, "./testdb", &db);
    
    if (!status.ok()) {
        std::cerr << "Unable to open/create database: " << status.ToString() << std::endl;
        return 1;
    }

    std::cout << "Database opened successfully" << std::endl;

    // 关闭数据库
    delete db;
    return 0;
}

写入和读取

#include <leveldb/db.h>
#include <iostream>
#include <string>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 写入数据
    std::string key = "user:1001";
    std::string value = "{\"name\":\"Alice\",\"age\":25}";
    
    leveldb::Status status = db->Put(leveldb::WriteOptions(), key, value);
    
    if (!status.ok()) {
        std::cerr << "Put failed: " << status.ToString() << std::endl;
    } else {
        std::cout << "Data written successfully" << std::endl;
    }

    // 读取数据
    std::string result;
    status = db->Get(leveldb::ReadOptions(), key, &result);
    
    if (status.ok()) {
        std::cout << "Read: " << result << std::endl;
    } else if (status.IsNotFound()) {
        std::cout << "Key not found" << std::endl;
    }

    delete db;
    return 0;
}

删除数据

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 写入数据
    db->Put(leveldb::WriteOptions(), "temp_key", "temp_value");

    // 删除数据
    leveldb::Status status = db->Delete(leveldb::WriteOptions(), "temp_key");
    
    if (status.ok()) {
        std::cout << "Data deleted successfully" << std::endl;
    }

    // 验证删除
    std::string result;
    status = db->Get(leveldb::ReadOptions(), "temp_key", &result);
    
    if (status.IsNotFound()) {
        std::cout << "Key deleted confirmed" << std::endl;
    }

    delete db;
    return 0;
}

🔧 批量操作

批量写入

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 创建批量写入对象
    leveldb::WriteBatch batch;
    
    // 添加多个操作
    batch.Put("key1", "value1");
    batch.Put("key2", "value2");
    batch.Put("key3", "value3");
    batch.Delete("old_key");

    // 执行批量写入
    leveldb::Status status = db->Write(leveldb::WriteOptions(), &batch);
    
    if (status.ok()) {
        std::cout << "Batch write successful" << std::endl;
    }

    delete db;
    return 0;
}

📖 遍历数据

范围查询

#include <leveldb/db.h>
#include <iostream>
#include <string>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 写入一些数据
    for (int i = 0; i < 10; i++) {
        db->Put(leveldb::WriteOptions(), "key" + std::to_string(i), "value" + std::to_string(i));
    }

    // 创建迭代器
    leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());

    // 遍历所有数据
    std::cout << "All data:" << std::endl;
    for (it->SeekToFirst(); it->Valid(); it->Next()) {
        std::cout << "  " << it->key().ToString() 
                  << " : " << it->value().ToString() << std::endl;
    }

    // 遍历范围
    std::cout << "\nRange query (key2 to key5):" << std::endl;
    for (it->Seek("key2"); it->Valid() && it->key().ToString() <= "key5"; it->Next()) {
        std::cout << "  " << it->key().ToString() 
                  << " : " << it->value().ToString() << std::endl;
    }

    delete it;
    delete db;
    return 0;
}

⚙️ 高级配置

压缩和缓存设置

#include <leveldb/db.h>
#include <leveldb/cache.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    
    // 创建 100MB 的块缓存
    options.block_cache = leveldb::NewLRUCache(100 * 1024 * 1024);
    
    // 启用压缩
    options.compression = leveldb::kSnappyCompression;
    
    // 如果数据库不存在则创建
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 使用数据库...

    // 清理
    delete db;
    delete options.block_cache;
    
    return 0;
}

快照

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB::Open(options, "./testdb", &db);

    // 写入一些数据
    db->Put(leveldb::WriteOptions(), "key1", "value1");
    db->Put(leveldb::WriteOptions(), "key2", "value2");

    // 创建快照
    const leveldb::Snapshot* snapshot = db->GetSnapshot();

    // 继续写入数据
    db->Put(leveldb::WriteOptions(), "key1", "new_value1");

    // 从快照读取(读取的是快照时的数据)
    leveldb::ReadOptions read_options;
    read_options.snapshot = snapshot;
    
    std::string value;
    db->Get(read_options, "key1", &value);
    std::cout << "From snapshot: " << value << std::endl;  // value1

    // 释放快照
    db->ReleaseSnapshot(snapshot);

    delete db;
    return 0;
}

💼 实际应用示例

简单的 KV 封装

#include <leveldb/db.h>
#include <string>
#include <iostream>

class LevelDBWrapper {
private:
    leveldb::DB* db_;

public:
    LevelDBWrapper(const std::string& path) : db_(nullptr) {
        leveldb::Options options;
        options.create_if_missing = true;

        leveldb::Status status = leveldb::DB::Open(options, path, &db_);
        
        if (!status.ok()) {
            std::cerr << "Failed to open database: " << status.ToString() << std::endl;
        }
    }

    ~LevelDBWrapper() {
        if (db_) {
            delete db_;
        }
    }

    bool put(const std::string& key, const std::string& value) {
        leveldb::Status status = db_->Put(leveldb::WriteOptions(), key, value);
        return status.ok();
    }

    bool get(const std::string& key, std::string& value) {
        leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
        return status.ok();
    }

    bool del(const std::string& key) {
        leveldb::Status status = db_->Delete(leveldb::WriteOptions(), key);
        return status.ok();
    }

    bool exists(const std::string& key) {
        std::string value;
        leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
        return status.ok() && !status.IsNotFound();
    }
};

int main() {
    LevelDBWrapper db("./mydb");

    // 写入
    db.put("name", "Alice");
    db.put("age", "25");

    // 读取
    std::string name;
    if (db.get("name", name)) {
        std::cout << "Name: " << name << std::endl;
    }

    // 检查存在
    if (db.exists("name")) {
        std::cout << "Key 'name' exists" << std::endl;
    }

    // 删除
    db.del("age");

    return 0;
}

📋 常用选项速查

选项 类型 说明
create_if_missing bool 如果数据库不存在则创建
error_if_exists bool 如果数据库已存在则报错
paranoid_checks bool 启用严格检查(增加开销)
write_buffer_size size_t 写入缓冲区大小(默认4MB)
max_open_files int 最大打开文件数
block_cache Cache* 块缓存对象
compression CompressionType 压缩类型(kNoCompression/kSnappyCompression)
💡 提示: LevelDB 按键排序存储数据,利用这一特性可以进行高效的范围查询。数据在磁盘上是按键的字典序组织的。
⚠️ 注意:

🔗 参考资料