#key-value-store #key-value-database #system-interface #database #virtual #filesystem #file-format

grebedb

轻量级嵌入式键值存储/数据库,通过虚拟文件系统接口支持文件

4个版本 (1个稳定版)

1.0.0 2021年6月4日
0.3.0 2021年4月20日
0.2.0 2021年4月7日
0.1.0 2021年3月29日

#155数据库实现

每月24次 下载
用于 grebedb-tool

MPL-2.0 许可证

140KB
3.5K SLoC

GrebeDB

GrebeDB是一个Rust库,提供了一个轻量级嵌入式键值存储/数据库,该数据库通过虚拟文件系统接口支持文件。它适用于偏好键值数据库接口而非直接操作文件格式的单进程应用程序。

Crates.io docs.rs

注意:尽管该库处于非常实用的状态,并且已经做了大量工作以确保其正确性和稳健性,但它尚未经过广泛的测试或用于生产环境。请谨慎使用,并定期备份重要数据。

设计摘要(局限性和保证)

由于键值存储太多,数据库的设计立即为您描述,以便您决定GrebeDB是否适合您的使用

  • 数据库实现为一个B+树,每个节点都保存到一个文件中。
    • 键和值都被视为二进制数据。没有对具有前缀的键进行优化。
    • 值与叶子节点一起存储。
    • 执行惰性删除。
  • 每个文件的大小不是固定的,可以根据存储的数据和配置选项显著变化。
  • 文件使用虚拟文件系统接口存储。实现可以是内存中的,也可以是真实磁盘上的,或您自己的实现。性能和持久性取决于文件系统。
  • 提供了诸如getputremovecursor等操作。不支持传统的事务,但flush操作提供了数据的原子保存。通过文件复制-on-writes、递增修订计数器和原子文件重命名提供内部一致性。
  • 可以使用Zstandard压缩文件。
  • 不支持并发。没有使用线程进行后台任务。

有关文件格式的详细信息,请参阅format.md

入门指南

请记住将grebedbcrate依赖项添加到您的Cargo.toml中。

GrebeDB 数据库以多个文件的形式存储在目录中。以下示例展示了如何使用给定路径和默认选项创建数据库:

let options = Options::default();
let mut db = Database::open_path("path/to/empty/directory/", options)?;

存储、检索和删除键值对的操作与使用 get()put()remove() 函数一样简单。

db.put("my_key", "hello world")?;

println!("The value of my_key is {:?}", db.get("my_key")?);

db.remove("my_key")?;

println!("The value of my_key is now {:?}", db.get("my_key")?);

要获取所有键值对,请使用 cursor()

for (key, value) in db.cursor() {
    println!("key = {}, value = {}", key, value);
}

数据库使用内部缓存并自动延迟将数据写入文件系统。如果您想在某个时刻确保所有更改都已持久保存到文件系统,请使用 flush()。此操作在返回前以原子性保存数据,有效地模拟了事务。

db.flush()?;

提示:当插入大量项目时,为了最佳性能,请按顺序插入键。插入大量随机键将很慢,因为它需要打开、写入和关闭包含其位置的文件。

有关更多信息,请查看 示例目录docs.rs 上的 API 参考

特性

默认情况下,特性是启用的。

  • compression:启用 zstd crate 进行压缩。
  • file_lockingfslock 用于跨平台文件锁定。
  • systemgetrandomuuid 的依赖项。

要禁用它们,请在您的 Cargo.toml 文件中使用 default-features = false

工具

有关提供基本操作(如导入和导出以进行备份)和调试的命令行工具,请参阅 grebedb-tool

贡献

如果您有任何问题、错误修复或建议,请使用 GitHub Issues、Pull Requests 和 Discussions。

路线图

可能的改进

  • 更好的缓冲区参数 API。类型 &mut Vec<u8> 可能不够灵活。
  • 减少内部内存分配和复制。
  • 通过更智能的缓存减少磁盘 I/O。
  • 更多针对错误情况的测试。

不在范围内

以下非穷尽性的特性不在范围内,并且可能不会实现:

  • 增加数据结构复杂性的添加或修改(例如,支持反向游标方向)。
  • 将操作传统分组到具有提交和回滚的事务中。
  • 线程执行自动后台工作。
  • Async/.await 支持。

如果您需要更多功能或需要更好的性能,可能需要一个更强大的数据库,如具有 Rust 绑定的 RocksDB 或传统数据库 SQLite。

许可

版权 2021 Christopher Foo。许可协议为 Mozilla Public License 2.0。

依赖项

~1.9–3.5MB
~67K SLoC