3个版本
2.0.0-beta.4 | 2020年7月31日 |
---|---|
2.0.0-beta.3 | 2020年7月3日 |
2.0.0-beta.2 | 2020年6月30日 |
#2922 in 数据库接口
每月37次下载
用于 turingdb-server
27KB
253 行
Turing·DB
TuringDB 是一个用 Rust 编写的数据库,旨在实现分布式和水平扩展。它旨在作为不需要关系数据库或模式的替代品。
数据库由 Sled 键值存储支持
动机
创建这个数据库的动机是拥有一个具有 ACID 属性、速度、类型安全、非轮询的 changefeeds、多集群查询和复制的键值数据库。Rust 是速度、类型安全和编译时检查最适合的语言。此外,sled.rs
已被用作此数据库的嵌入式键值存储,因为它是无锁的、具有完全原子的操作、零拷贝读取、SSD 优化的日志存储,并且是用 Rust 编写的,因此继承了语言的所有美妙特性。
特性
数据库旨在是
- 非常简单易用的文档数据库
- 具有查找和范围功能
- 分区容错和一致性
- 提供实时推送能力,无需轮询,灵感来自 RethinkDB changefeeds
- 提供简单的连接操作
- 提供由 Raft 一致性算法支持的分布式能力
- 提供多集群查询能力
- 足够小,可以用作嵌入式数据库
- 足够小和快速,可以在嵌入式设备或大型服务器上使用
- 非常有趣易用
正在开发中的特性包括
- 复制
- 多集群查询
- 非轮询的 changefeeds,灵感来自 RethinkDB
- 支持 JSON
服务器使用
-
从 crates-io 安装
$ cargo install turingdb-server
-
启动服务器
$ turingdb-server
-
创建一个新的 cargo 仓库
$ cargo new my-app
-
编辑
Cargo.toml
文件#[dependencies] turingdb-helpers = #add the latest version here bincode = #add the latest version async-std = #add latest version here anyhow = # add latest version custom_codes = #add latest vesion
如果您已安装
cargo-edit
,则可以使用它而不是手动添加依赖项$ cargo add turingdb-helpers bincode async-std anyhow custom_codes
-
在编辑器中打开
src/main.rs
文件use async_std::net::TcpStream; use async_std::io::prelude::*; use serde::{Serialize, Deserialize}; use custom_codes::DbOps; const BUFFER_CAPACITY: usize = 64 * 1024; //16Kb const BUFFER_DATA_CAPACITY: usize = 1024 * 1024 * 16; // Db cannot hold data more than 16MB in size #[derive(Debug, Serialize, Deserialize)] struct DocumentQuery { db: String, document: Option<String>, } #[derive(Debug, Serialize, Deserialize)] pub (crate) struct FieldQuery { db: String, document: String, field: String, payload: Option<Vec<u8>>, } #[async_std::main] async fn main() -> anyhow::Result<()> { let db_create = "db0".as_bytes(); let mut packet = vec![0x02]; packet.extend_from_slice(&db_create); let mut buffer = [0; BUFFER_CAPACITY]; let mut container_buffer: Vec<u8> = Vec::new(); let mut bytes_read: usize; let mut current_buffer_size = 0_usize; let mut stream = TcpStream::connect("127.0.0.1:4343").await?; stream.write(&packet).await?; loop { bytes_read = stream.read(&mut buffer).await?; // Add the new buffer length to the current buffer size current_buffer_size += buffer[..bytes_read].len(); // Check if the current stream is less than the buffer capacity, if so all data has been received if buffer[..bytes_read].len() < BUFFER_CAPACITY { // Ensure that the data is appended before being deserialized by bincode container_buffer.append(&mut buffer[..bytes_read].to_owned()); dbg!(&container_buffer); dbg!(bincode::deserialize::<DbOps>(&container_buffer).unwrap()); break; } // Append data to buffer container_buffer.append(&mut buffer[..bytes_read].to_owned()); } Ok(()) }
数据库支持的当前查询方法
-
仓库查询
turingdb_helpers::RepoQuery::create()
在当前目录中创建一个新的仓库turingdb_helpers::RepoQuery::drop()
在当前目录中删除一个仓库
-
数据库查询
-
DbQuery::create()
在仓库中创建一个新数据库use turingdb_helpers::DatabaseQuery; let mut foo = DatabaseQuery::new().await; foo .db("db_name").await .create().await;
-
DbQuery::drop()
在仓库中删除一个数据库use turingdb_helpers::DatabaseQuery; let mut foo = DatabaseQuery::new().await; foo .db("db_name").await .drop().await;
-
DbQuery::list()
列出仓库中的所有数据库use turingdb_helpers::DatabaseQuery; let mut foo = Database::new().await; foo.drop().await;
-
-
文档查询
-
DocumentQuery::create()
在数据库中创建一个文档use turingdb_helpers::DocumentQuery; let mut foo = DocumentQuery::new().await; foo .db("db_name").await .document("document_name").await .create().await;
-
DocumentQuery::drop()
在数据库中删除一个文档use turingdb_helpers::DocumentQuery; let mut foo = DocumentQuery::new().await; foo .db("db_name").await .document("document_name").await .drop().await;
-
DocumentQuery::list()
列出数据库中的所有文档use turingdb_helpers::DocumentQuery; let mut foo = DocumentQuery::new().await; foo .db("db_name").await .list().await;
-
-
字段查询
-
Field::set()
基于键在文档中创建一个字段use turingdb_helpers::FieldQuery; let mut foo = FieldQuery::new().await; let data = "my_data_converted_into_bytes".as_bytes(); foo .db("db_name").await .document("document_name").await .field("field_name").await .payload(data).await .set().await
-
Field::get()
基于键获取文档中的字段use turingdb_helpers::FieldQuery; let mut foo = FieldQuery::new().await; foo .db("db_name").await .document("document_name").await .field("field_name").await .get().await
-
Field::modify()
基于键更新文档中的字段use turingdb_helpers::FieldQuery; let mut foo = FieldQuery::new().await; let data = "my_new_data_converted_into_bytes".as_bytes(); foo .db("db_name").await .document("document_name").await .field("field_name").await .payload(data).await .modify().await
-
Field::remove()
基于键删除文档中的字段use turingdb_helpers::FieldQuery; let mut foo = FieldQuery::new().await; foo .db("db_name").await .document("document_name").await .field("field_name").await .remove().await
-
Field::list()
获取所有字段的键use turingdb_helpers::FieldQuery; let mut foo = FieldQuery::new().await; foo .db("db_name").await .document("document_name").await .list().await
-
警告
一个文档不能存储超过 16MiB
的数据,如果超过此阈值,将产生来自 custom_codes
crate的 DbOps::EncounteredErrors([TuringDB::<GLOBAL>::(ERROR)-BUFFER_CAPACITY_EXCEEDED_16MB])
贡献
我们遵循 Rust行为准则 来进行贡献
许可证
对本项目的所有代码贡献都必须以Apache许可证授权
致谢
本项目中使用的所有库均受其自身许可证的约束
依赖关系
~0.8–1.4MB
~32K SLoC