Rust嵌入式数据库引擎libmdbx的使用,libmdbx提供高性能键值存储和事务支持
libmdbx-rs
Rust绑定库用于libmdbx
许可证
此仓库内的所有代码均根据Mozilla公共许可证v2.0授权
元数据
包:cargo/libmdbx@0.6.1
大约1个月前发布
2024版本
MPL-2.0
42.8 KiB
安装
在您的项目目录中运行以下Cargo命令:
cargo add libmdbx
或在您的Cargo.toml中添加以下行:
libmdbx = “0.6.1”
文档
代码仓库
所有者
Artem Vorotnikov
分类
数据库接口
报告包
use libmdbx::{Environment, EnvironmentKind, Transaction, WriteFlags};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建数据库环境
let env = Environment::new()
.open(Path::new("mydb"))?;
// 开始一个写事务
let txn = env.begin_rw_txn()?;
// 打开或创建数据库
let db = txn.open_db(None)?;
// 插入键值对
txn.put(&db, b"key1", b"value1", WriteFlags::empty())?;
txn.put(&db, b"key2", b"value2", WriteFlags::empty())?;
// 提交事务
txn.commit()?;
// 开始一个读事务
let txn = env.begin_ro_txn()?;
// 读取数据
let value1: Vec<u8> = txn.get(&db, b"key1")?.unwrap().to_vec();
let value2: Vec<u8> = txn.get(&db, b"key2")?.unwrap().to_vec();
println!("key1: {}", String::from_utf8_lossy(&value1));
println!("key2: {}", String::from_utf8_lossy(&value2));
// 事务会自动在作用域结束时提交
Ok(())
}
完整示例demo:
use libmdbx::{Environment, EnvironmentKind, Transaction, WriteFlags};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建数据库环境
let env = Environment::new()
.open(Path::new("mydb"))?;
// 开始一个写事务
let txn = env.begin_rw_txn()?;
// 打开或创建数据库
let db = txn.open_db(None)?;
// 插入键值对
txn.put(&db, b"key1", b"value1", WriteFlags::empty())?;
txn.put(&db, b"key2", b"value2", WriteFlags::empty())?;
// 提交事务
txn.commit()?;
// 开始一个读事务
let txn = env.begin_ro_txn()?;
// 读取数据
let value1: Vec<u8> = txn.get(&db, b"key1")?.unwrap().to_vec();
let value2: Vec<u8> = txn.get(&db, b"key2")?.unwrap().to_vec();
println!("key1: {}", String::from_utf8_lossy(&value1));
println!("key2: {}", String::from_utf8_lossy(&value2));
// 事务会自动在作用域结束时提交
Ok(())
}
1 回复
Rust嵌入式数据库引擎libmdbx的使用指南
概述
libmdbx是一个高性能的嵌入式键值存储引擎,专为Rust语言设计。它提供了ACID事务支持、零拷贝访问和内存映射I/O等特性,特别适合需要高吞吐量和低延迟的应用场景。
主要特性
- 支持多版本并发控制(MVCC)
- 完全事务性(ACID兼容)
- 内存映射存储架构
- 零拷贝数据访问
- 跨平台支持
安装方法
在Cargo.toml中添加依赖:
[dependencies]
libmdbx = "0.8"
基本使用方法
1. 创建数据库环境
use libmdbx::{Environment, EnvironmentFlags, WriteFlags};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建或打开数据库环境
let env = Environment::new()
.set_max_dbs(10)
.set_flags(EnvironmentFlags::default())
.open("my_database")?;
Ok(())
}
2. 创建数据库和表
let db = env.create_database(Some("my_table"), None)?;
3. 写入数据
let txn = env.begin_rw_txn()?;
{
let db = txn.open_db(Some("my_table"))?;
txn.put(&db, b"key1", b"value1", WriteFlags::empty())?;
txn.put(&db, b"key2", b"value2", WriteFlags::empty())?;
}
txn.commit()?;
4. 读取数据
let txn = env.begin_ro_txn()?;
let db = txn.open_db(Some("my_table"))?;
if let Some(value) = txn.get(&db, b"key1")? {
println!("Value: {:?}", value);
}
5. 使用事务
let txn = env.begin_rw_txn()?;
let db = txn.open_db(Some("my_table"))?;
// 事务操作
txn.put(&db, b"key3", b"value3", WriteFlags::empty())?;
txn.del(&db, b"key1", None)?;
// 提交事务
txn.commit()?;
6. 迭代器使用
let txn = env.begin_ro_txn()?;
let db = txn.open_db(Some("my_table"))?;
let cursor = txn.cursor(&db)?;
// 遍历所有键值对
for result in cursor.into_iter() {
let (key, value) = result?;
println!("Key: {:?}, Value: {:?}", key, value);
}
高级配置示例
use libmdbx::{Environment, EnvironmentFlags, Geometry};
let env = Environment::new()
.set_max_dbs(20)
.set_geometry(Geometry {
size: Some(1024 * 1024 * 1024), // 1GB
growth_step: Some(1024 * 1024), // 1MB
shrink_threshold: None,
page_size: None,
})
.set_flags(EnvironmentFlags::NO_SUB_DIR | EnvironmentFlags::NO_TLS)
.open("advanced_db")?;
错误处理
match env.create_database(Some("my_table"), None) {
Ok(db) => println!("Database created successfully"),
Err(e) => eprintln!("Error creating database: {}", e),
}
性能优化建议
- 使用适当的内存映射大小
- 合理设置页面大小
- 批量操作时使用单个事务
- 根据读写比例选择合适的标志位
注意事项
- 确保有足够的磁盘空间
- 定期备份重要数据
- 在多线程环境中正确处理事务生命周期
完整示例demo
use libmdbx::{Environment, EnvironmentFlags, WriteFlags, Geometry};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// 创建数据库环境
let env = Environment::new()
.set_max_dbs(5)
.set_geometry(Geometry {
size: Some(100 * 1024 * 1024), // 100MB
growth_step: Some(1024 * 1024), // 1MB
shrink_threshold: None,
page_size: None,
})
.set_flags(EnvironmentFlags::NO_SUB_DIR)
.open("example_db")?;
// 创建数据库表
let db = env.create_database(Some("users"), None)?;
println!("Database 'users' created successfully");
// 写入数据事务
let mut txn = env.begin_rw_txn()?;
{
let db_handle = txn.open_db(Some("users"))?;
// 写入多个键值对
txn.put(&db_handle, b"user:1", b"Alice", WriteFlags::empty())?;
txn.put(&db_handle, b"user:2", b"Bob", WriteFlags::empty())?;
txn.put(&db_handle, b"user:3", b"Charlie", WriteFlags::empty())?;
println!("Data written successfully");
}
txn.commit()?;
// 读取数据事务
let txn = env.begin_ro_txn()?;
{
let db_handle = txn.open_db(Some("users"))?;
// 读取单个键值
if let Some(value) = txn.get(&db_handle, b"user:1")? {
println!("User 1: {:?}", String::from_utf8_lossy(&value));
}
// 使用迭代器遍历所有数据
println!("\nAll users:");
let cursor = txn.cursor(&db_handle)?;
for result in cursor.into_iter() {
let (key, value) = result?;
println!("Key: {:?}, Value: {:?}",
String::from_utf8_lossy(&key),
String::from_utf8_lossy(&value));
}
}
// 更新数据事务
let mut txn = env.begin_rw_txn()?;
{
let db_handle = txn.open_db(Some("users"))?;
// 更新用户数据
txn.put(&db_handle, b"user:2", b"Robert", WriteFlags::empty())?;
// 删除用户数据
txn.del(&db_handle, b"user:3", None)?;
println!("\nData updated: user:2 changed to Robert, user:3 deleted");
}
txn.commit()?;
// 验证更新结果
let txn = env.begin_ro_txn()?;
{
let db_handle = txn.open_db(Some("users"))?;
let cursor = txn.cursor(&db_handle)?;
println!("\nFinal user list:");
for result in cursor.into_iter() {
let (key, value) = result?;
println!("Key: {:?}, Value: {:?}",
String::from_utf8_lossy(&key),
String::from_utf8_lossy(&value));
}
}
Ok(())
}
这个库为Rust开发者提供了强大的嵌入式数据库解决方案,特别适合需要高性能键值存储的应用场景。