6个版本
0.2.4 | 2020年3月11日 |
---|---|
0.2.3 | 2020年3月5日 |
0.2.1 | 2020年2月25日 |
0.1.0 | 2020年2月10日 |
#1585 在 数据库接口
44 每月下载量
用于 6 crates
82KB
497 行
CQLDb
轻量级、可扩展的基于数组的存储解决方案,目前包含以下开箱即用的存储类型(也支持自定义类型)
- U64(无符号64位整数)
- F64(64位浮点数)
- NullableF64(可空64位浮点数)
- TinyText(255字符UTF-8字符串)
该项目通过将文件系统视为N维数组来工作,从而消除了扫描以查找项的需要。目前,必须在创建数据库时指定维数的数量,然而每个维度(除了最后一个)都可以按需增长。
该项目最初是针对存储大量关系型时间序列数据而构建的,然而我正在寻找在其它项目中探索其他用途的方法。
数据库是单索引的。
项目结构
该项目分为两个核心子项目,cql_db 和 cql_model,以及每个支持的类型一个子项目,位于 cql_storage_types 文件夹中。
cql_db 子项目包含核心逻辑,该逻辑协调特定类型的逻辑和基于数组的逻辑,使整个系统作为一个数据库运行。它依赖于 cql_model 和 U64 类型。
cql_model 子项目包含由 cql_db 和存储类型消耗的接口,并由所有子项目引用。
存储类型特定项目包含用于从文件读取/写入特定类型的特定代码,实现了 cql_model 子项目中的接口。
要使用此项目,您需要导入 cql_db 子项目,以及您想要使用的每个存储类型,或者 cql_model 和您自己实现的特质的特质的实现 - 如果您想使用其他类型的话。
下面表格中提供了所有已发布组件的Rustdocs(带示例)和crates
仓库链接 | Crates | 文档 | 描述 |
---|---|---|---|
CQL Db | crates.io | docs.rs | 核心CQL数据库引擎 |
CQL Model | crates.io | docs.rs | 核心CQL数据库模型/接口 |
U64 | crates.io | docs.rs | 无符号64位整数存储支持 |
F64 | 未发布 | 未发布 | 64位浮点数存储支持 |
NullableF64 | crates.io | docs.rs | 支持可空64位浮点数存储 |
TinyText | crates.io | docs.rs | 支持255字符UTF-8字符串存储 |
破坏性更改
由于本项目是针对文件系统的数据存储解决方案,一些更改可能会改变底层数据的预期结构,阻止一个版本正确利用在另一个版本上创建的数据库。截至1.0.0版本,次要版本(中间数字)将递增,破坏性版本列在下面的表中。如果您需要在这两个版本之间进行升级,我建议您从早期版本中读取整个数据库,并将其写入新版本的新数据库中,我将尽力改进这一点。请小心。
Crates | 破坏性版本 | 描述 |
---|---|---|
cql_db | 0.2.0 | 在关键文件和数据库文件中进行的更改。提交 048e533 和 7dcaf7c |
入门
要开始,选择一个或多个存储类型(例如使用NullableF64),并将其作为依赖项添加到您的Cargo.toml中,同时包含核心cql_db crate
[dependencies]
//... (any existing dependencies you may have)
cql_db = "^0.2"
cql_nullable_f64 = "^0.2"
然后您需要创建一个文件夹,用于存放数据库,然后尝试以下操作
use std::io;
use std::io::{ Cursor, SeekFrom, Seek };
use cql_nullable_f64::{ NullableF64, unpack_stream };
const DATABASE_LOCATION: &str = "PATH_TO_YOUR_DATABASE_DIRECTORY";
const N_VALUES_TO_READ: usize = 3;
pub fn example_cql() -> io::Result<()> {
let base_point = [1];
let value1 = Some(-1.6);
let value3 = Some(5.4);
// creates a one dimensional database, with a capacity of 3
cql_db::create_db::<NullableF64>(
DATABASE_LOCATION,
&[3]
)?;
// writes Some(-1.6) to [0]
cql_db::write_value::<NullableF64>(
DATABASE_LOCATION,
&base_point,
value1
)?;
// writes Some(5.4) to [2]
cql_db::write_value::<NullableF64>(
DATABASE_LOCATION,
&[base_point[0] + 2],
value3
)?;
let mut result: [Option<f64>; N_VALUES_TO_READ] = [None; N_VALUES_TO_READ];
let mut stream = Cursor::new(Vec::new());
// reads 3 points from [0] into `stream`
cql_db::read_to_stream::<NullableF64>(
DATABASE_LOCATION,
&mut stream,
&base_point,
N_VALUES_TO_READ as u64
)?;
// returns to the start of the stream
stream.seek(SeekFrom::Start(0)).unwrap();
// unpacks the stream value by value into the result[]
unpack_stream(&mut stream, N_VALUES_TO_READ, |idx, value| {
result[idx] = value
})?;
assert_eq!(result[0], value1);
assert_eq!(result[1], None);
assert_eq!(result[2], value3);
}
更多示例可以在rustdocs中找到。
基准测试
以下提供了U64类型的基准测试,它们相当基础(并且是四舍五入的),目的是给出相对成本的粗略估计。完整的基准测试代码可以在github中找到,可以使用以下命令运行:rustup run nightly cargo bench
。其他类型的基准测试可以在该类型的相应文档中找到。
操作 | 数据库维度 | 未检查的平均时间(ns) | 平均时间(ns) |
---|---|---|---|
单点读取 | 1 | 2 450 (+/- 300) | 7 500 (+/- 600) |
单点读取 | 4 | 14 850 (+/- 1 000) | 37 550 (+/- 2 300) |
单点写入 | 1 | 2 800 (+/- 400) | 7 700 (+/- 400) |
单点写入 | 4 | 15 400 (+/- 2 500) | 37 700 (+/- 3 000) |
流读取1个点 | 1 | 2 500 (+/- 300) | 10 000 (+/- 850) |
流读取1个点 | 4 | 14 900 (+/- 600) | 42 500 (+/- 6 500) |
流读取50,000个点 | 1 | 27 650 000 (+/- 31 000) | 27 630 000 (+/- 180 000) |
流读取50,000个点 | 4 | 27 660 000 (+/- 1 200 000) | 27 620 000 (+/- 480 000) |
许可证
根据您的要求,许可协议为以下之一
- Apache许可证,版本2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的,您有意提交的任何贡献,都应如上所述双重许可,不附加任何额外条款或条件。
依赖项
~120KB