Key-value stores

RecipeCratesCategories
heedheedcat-database
rocksdbrocksdbcat-database

heed

heed heed-crates.io heed-github heed-lib.rs cat-data-structures cat-database

heed is a fully-typed LMDB wrapper. LMDB (Lightning Memory-Mapped Database) is a fast and efficient embedded database library that provides key/value storage. Use heed for:

Advantages include speed, minimal memory footprint, embedded use, memory mapping, and ACID (Atomicity, Consistency, Isolation, Durability) properties. It is not ideal for huge datasets, complex queries, or network access.

use heed::Database;
use heed::EnvOpenOptions;
use heed::types::*;

// `heed` (and `heed3`) are high-level wrappers of LMDB.
// Lightning Memory-Mapped Database (LMDB) is an embedded transactional
// database in the form of a key-value store.

fn main() -> anyhow::Result<()> {
    // Open a database
    let dir = tempfile::tempdir().unwrap();
    let env = unsafe {
        EnvOpenOptions::new()
            .map_size(1024 * 1024 * 10) // 10 MiB
            .max_dbs(10)
            .open(dir.path())?
    };

    // Create a transaction with read and write access for use with the
    // environment.
    let mut wtxn = env.write_txn()?;

    // Open the default unnamed database
    let db: Database<U32<byteorder::NativeEndian>, Str> =
        env.create_database(&mut wtxn, None)?;

    // Write data to the database
    db.put(&mut wtxn, &1, "Hello, world!")?;
    wtxn.commit()?;

    // Open a read transaction
    let rtxn = env.read_txn()?;
    // Read data from the database
    let value = db.get(&rtxn, &1)?.unwrap();
    println!("Value: {}", value);
    assert_eq!(value, "Hello, world!");

    Ok(())
}

rocksdb

rocksdb rocksdb-crates.io rocksdb-github rocksdb-lib.rs cat-database

rocksdb is a Rust wrapper for Facebook's RocksDB embeddable database. RocksDB is a high performance database for key-value data. Use rocksdb:

  • As the storage engine for other databases (MySQL, MongoDB, TiKV...),
  • For caching,
  • To handle time-series data, indexes for search engines, persistent message queues

RocksDB is employed in stream processing frameworks like Apache Flink and Kafka Streams to maintain the state of streaming applications.

RocksDB is great for performance, scalability, flexibility, embeddability. Avoid when dealing with complex SQL or distributed transactions.


// Example using Facebook's RocksDB embeddable database.

// Ensure you have the RocksDB C++ library installed on your system, because the
// Rust `rocksdb` crate is just a wrapper around the native C++ RocksDB library.
// If you're on `Ubuntu`, you can install it with:
// sudo apt-get install librocksdb-dev
// You will also need: Clang and LLVM.

use rocksdb::DB;
use rocksdb::Options;

fn main() -> anyhow::Result<()> {
    // Create a new temporary directory to store the database,
    // which will be deleted when `tempdir` goes out of scope
    let tempdir = tempfile::Builder::new()
        .prefix("rocksdb_storage")
        .tempdir()
        .expect(
            "Failed to create the temporary directory for `rocksdb` storage",
        );
    let path = tempdir.path();
    // In real life, use e.g.: let path = "my_rocksdb_path";
    {
        // Open a RocksDB database.
        // This will create a new database if it doesn't exist.
        let db = DB::open_default(path)?;

        // Insert some key-value pairs:
        db.put(b"key1", b"value1")?;
        db.put(b"key2", b"value2")?;

        // Retrieve a value by its key:
        match db.get(b"key1")? {
            Some(value) => println!(
                "Found key1 with value: {}",
                String::from_utf8_lossy(&value)
            ),
            None => println!("key1 not found"),
        }

        // Delete a key-value pair:
        db.delete(b"key1")?;

        // Try to get the deleted key:
        match db.get(b"key1")? {
            Some(value) => println!(
                "Found key1 with value: {}",
                String::from_utf8_lossy(&value)
            ),
            None => println!("key1 not found after deletion"),
        }
    }
    let _ = DB::destroy(&Options::default(), path);

    Ok(())
}