18 个版本
0.2.2 | 2022 年 9 月 21 日 |
---|---|
0.2.1 | 2022 年 9 月 20 日 |
0.1.14 | 2022 年 9 月 13 日 |
0.1.13 | 2022 年 8 月 6 日 |
0.1.0 | 2022 年 3 月 30 日 |
1814 在 数据库接口
每月 35 次下载
24KB
472 行
非常初稿,只是记录了一些想法。
hmdb
具有以下属性的嵌入式数据库:
- 读取优化
- 持久化
- 事务性
- 内存中
- 键值存储
- Rust 中定义并强制执行模式
将一组特质应用于适当的结构,允许并发访问一组 HashMap
。写入通过只追加日志写入磁盘。日志可以通过快照进行压缩。快照是原子写入的,日志的追加是有限范围的,如果它们损坏。压缩可以在单独的线程上自动发生,或者当应用程序认为这是合适的时候。数据库可以配置为不同的一致性保证(缓冲日志)并且可以配置为在多个非协作进程共享数据目录的环境中(文件锁+无日志缓冲区)。优化延迟和紧凑的磁盘格式。
您对模式的所有知识,您都可以在编译时表达给数据库。您可以在 Rust 中指定哪些表存在以及这些表有什么键和值。数据库支持实现 serde
特质的任何内容,并使用 bincode
作为磁盘格式(经过战斗测试的性能和紧凑性的局部优化)。无需自己管理映射到和从数据库特定类型。
目标用途
定义模式
schema! {
SchemaV1 {
accounts: <Username, Account>,
files: <Uuid, EncryptedFileMetadata>
}
}
在底层,这将生成结构 SchemaV1
,您可以使用它这样做
fn main() {
let db = SchemaV1::init("data.db");
}
SchemaV1
是您的类型,但它将具有从该包中实现的各种特质。这些特质包括 Initialize
,它允许您从磁盘启动数据库,初始化将使用代表您的 OnDiskFormat
的关联类型。
您可以直接与您的表交互
fn main() {
let db = SchemaV1::init("data.db");
db.accounts.insert(Username::from("parth"), Account { ... });
let account = db.accounts.get(Username::from("parth"));
db.files.insert(meta.id, meta);
let file = db.files.get(meta.id);
}
这些类型不是基于使用隐式推断的,您在表示模式的一个位置中指定它们。
如果您想演变您的模式,您会这样做
schema! {
SchemaV1 {
accounts: <Username, Account>,
files: <Uuid, EncryptedFileMetadata>
}
}
schema! {
SchemaV2 {
accounts: <Username, AccountV2>,
files: <Uuid, EncryptedFileMetadata>
}
}
fn main() {
let old = SchemaV1::init("data.db");
let new = SchemaV2::init("data-v2.db");
old.accounts
.iter()
.map(|key, value| new.accounts.insert(key, value.into()));
old.files
.iter()
.map(|key, value| new.files.insert(key, value.into()));
// Migration successful, safe to delete data.db
}
基本事务体验
schema! {
SchemaV1 {
accounts: <Username, Account>,
files: <Uuid, EncryptedFileMetadata>
}
}
fn main() {
let db = SchemaV1::init("data.db");
db.transaction(|accounts, files| {});
}
最基本和最原始的版本将仅锁定一切以进行事务处理。更高级的实现可以允许您指定要锁定的表。长期目标状态可能涉及无锁和一些乐观并发。
虽然这已经预期在使用lockbook时会显著提高速度,但通过实验最先进的状态可以获得更多收益
依赖项
约1–1.7MB
约35K SLoC