6个版本
使用旧的Rust 2015
0.3.0 | 2018年4月19日 |
---|---|
0.2.1 | 2017年8月5日 |
0.1.2 | 2017年7月22日 |
#1325 在 数据库接口
41 每月下载量
在 2 crates 中使用
26KB
171 行
MVDB: 最小可行(伪)数据库
你是否曾经想过:“我想持久化一些数据,但又懒得好好做或高效地做”?好吧,你找到了合适的库。
如果你的用例是
- 很少写,但读很多
- 数据访问在多个线程之间共享
- 你的数据结构不是特别大
- 你已经在使用
Serde
序列化一些或全部数据 - 你的用例感觉太简单,连
sqlite
都可以用 - 你的数据格式/模式永远不会改变,或者只通过添加来改变,或者你愿意自己处理迁移
那么你可能喜欢 mvdb
!
它是如何工作的
mvdb
接收一个 Serializable
和 Deserializable
Rust数据结构,并使用 serde_json
在文件中表示这些数据。在初始文件加载后,所有读取访问都是从内存中进行的,而不是从文件中重新读取。在任意可变或读写访问之后,会检查数据内容的更改。如果内容已修改,则会将其推回文件。所有访问,只读和读写,都是原子操作。
通过闭包以事务方式访问结构,应注意不要在这些闭包中阻塞,因为这会阻止其他消费者在闭包完成之前访问数据。
将其放入你的项目中
# in Cargo.toml:
[dependencies]
mvdb = "0.2"
# in your Rust code:
extern crate mvdb;
示例
[macro_use] extern crate serde_derive;
extern crate serde;
extern crate mvdb;
use std::path::Path;
use mvdb::Mvdb;
#[derive(Deserialize, Serialize)]
struct DemoData {
foo: String,
bar: Vec<u8>,
baz: String,
}
fn main() {
let file = Path::new("demo.json");
let my_data: Mvdb<DemoData> = Mvdb::from_file(&file)
.expect("File does not exist, or schema mismatch");
// Read access
let foo_from_disk = my_data.access(|db| db.foo.clone())
.expect("Failed to access file");
// Write access
my_data.access_mut(|db: &mut DemoData| {
db.baz = "New Value".into();
}).expect("Failed to access file");
}
查看更大的示例 这里,或者克隆后运行 cargo run --example demo
。
警告
文件写入和性能
通常,mvdb
不是作为高性能数据库来使用的,而是用于很少更改的数据,例如每天更新一次令牌、偶尔添加信息或可以动态更改的配置。《strong>每次结构中的数据更改时,整个文件都将被重写。
如果您有一些字段变化很快,但不需要持久化到磁盘,例如消息的 VecDeque
,您可以使用 serde 的 #[skip]
指令来省略此字段,并且对这些字段的写入不会导致对底层文件的写入。 mvdb
也会尊重其他 Serde 属性,可以根据需要影响行为。
模式
mvdb
不会尝试处理模式,并且无法加载任何与当前已知模式不匹配的文件。可以使用 Serde 提供的机制来解决这个问题,请参阅此 问题跟踪 以及相关的 Reddit 线程。
但我想使用 (bincode|toml|其他),而不是 JSON!
我希望将来也能支持这些!请查看 此跟踪问题 了解阻力和在该方面的进展。
美化打印
所有创建新的 mvdb
的方法都提供了一个 _pretty
变体。这将使用美化打印的 JSON 存储内容,但会增加额外的空间。这在开发期间或当预期人类将修改或检查存储的内容时很有用。
默认值
如果您要存储的数据实现了 Default
特性,无论是通过 #[derive(Default)]
还是手动实现该特性,则可以使用 from_file_or_default
方法。这将尝试加载文件,如果失败,则创建一个包含默认数据的新文件。这对于具有合理默认值的配置文件或在首次运行时预期生成文件的场景很有用。
许可证
mvdb
在 MIT 许可证下授权。
依赖项
~2.9–4.5MB
~90K SLoC