5个版本 (1个稳定版)

2.0.0 2020年12月16日
2.0.0-beta.42020年7月31日
2.0.0-beta.32020年7月3日
2.0.0-beta.22020年6月30日

#2165数据库接口

每月44次下载
用于 turingdb-server

Apache-2.0

29KB
393

Turing·DB

Turing·DB Logo

TuringDB是一个用Rust编写的数据库,旨在分布式和水平扩展。它旨在替代你不需要关系型数据库或模式的地方。

数据库由Sled键值存储支持

动机

这个数据库背后的动机是拥有一个具有ACID属性、速度、类型安全、无轮询的更改流、多集群查询和复制的键值数据库。Rust最适合速度、类型安全和编译时检查。此外,sled.rs已经被用作该数据库的嵌入式键值存储,因为它是无锁的,具有完全原子的操作,零拷贝读取,SSD优化的日志存储,并且是用Rust编写的,因此继承了语言的所有优点。

特性

数据库旨在成为

  1. 真正简单易用的文档数据库
  2. 具有查找和范围能力
  3. 分区容错和一致
  4. 提供无轮询的实时推送能力,灵感来自RethinkDB更改流
  5. 提供简单的连接
  6. 提供可选的由Raft共识算法支持的分布式能力
  7. 提供可选的多集群查询
  8. 足够小,可以用作嵌入式数据库
  9. 足够小和快,可以在嵌入式设备或大型服务器上使用
  10. 非常有趣易用

正在开发中的特性包括

  1. 复制
  2. 多集群查询
  3. 无轮询的更改流,灵感来自RethinkDB
  4. JSON支持

服务器使用

  1. 从crates-io安装

    $ cargo install turingdb-server
    
  2. 启动服务器

    $ turingdb-server
    
  3. 创建一个新的cargo仓库

    $ cargo new my-app
    
  4. 编辑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
    
  5. 在编辑器中打开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(())
    }
    

数据库支持的当前查询方法

  1. 仓库查询

    • turingdb_helpers::RepoQuery::create() 在当前目录中创建一个新的仓库
    • turingdb_helpers::RepoQuery::drop() 在当前目录中删除一个仓库
  2. 数据库查询

    • 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;
      
  3. 文档查询

    • 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;
      
  4. 字段查询

    • 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 包的 DbOps::EncounteredErrors([TuringDB::<GLOBAL>::(ERROR)-BUFFER_CAPACITY_EXCEEDED_16MB])

贡献

我们在贡献过程中遵循 Rust 行为准则

许可

对本项目的所有代码贡献都必须根据 Apache 许可证授权

致谢

本项目中使用的所有库均受其自身许可证的约束

依赖项

~3.5–4.5MB
~80K SLoC