掘金 后端 ( ) • 2024-05-07 13:43

Rust嵌入式专属语言的嵌入式数据库native_db

大家好,我是梦兽。关注梦兽编程微信公众号,菜单微信群即可进群一起讨论WEB技术开发。

今天给大家介绍一款Rust语言专用的嵌入式数据库。一般嵌入式数据库使用数据库存储方案为Sqlite3,比如安卓里的本地数据库就是使用Sqlite3。如果你正在使用Rust可以试试native_db。

native_db

native_db 是一个用 Rust 语言编写的嵌入式数据库库。它旨在为多平台应用程序(包括服务器、桌面和移动设备)提供一个快速的、即插即用的数据库解决方案。以下是 native_db 的一些关键特性和信息:

  1. 简单 API: 提供了易于使用的接口。
  2. 支持多种索引:包括主键、次键、唯一和非唯一索引,以及可选索引。
  3. 最小化样板代码:通过基准测试可以看到其简洁性。
  4. 透明的序列化/反序列化:使用 native_model 进行。
  5. 自动模型迁移:数据库模式变更时自动处理。
  6. 线程安全:提供完全符合 ACID 标准的事务处理,由 redb 支持。
  7. 实时订阅:可以对 insert、update 和 delete 操作进行实时订阅,并带有过滤器。
  8. 与所有 Rust 类型兼容:包括 enum、struct、tuple 等。
  9. 热快照:能够创建数据库的即时快照。

如何使用

要在您的 Rust 项目中使用 native_db,需要在 Cargo.toml 文件中添加以下依赖项:

[dependencies]
native_db = "0.6.0"
native_model = "0.4.14"

注意:native_db 需要 native_model 才能工作。Tauri要一起使用:native_db_tauri_vanilla

API 示例

use serde::{Deserialize, Serialize};
use native_db::*;
use native_model::{native_model, Model};

# 这里定义一个实例,基于redb
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
    #[primary_key]
    id: u32,
    #[secondary_key]
    name: String,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    // 初始化模型
    builder.define::<Item>()?;
    
    // 在内存中创建数据库
    let mut db = builder.create_in_memory()?;
    
    // 插入数据(开启读写事务)
    let rw = db.rw_transaction().unwrap();
    rw.insert(Item { id: 1, name: "red".to_string() })?;
    rw.insert(Item { id: 2, name: "green".to_string() })?;
    rw.insert(Item { id: 3, name: "blue".to_string() })?;
    rw.commit()?;
    
    // 开启只读事务
    let r = db.r_transaction()?;
    // 通过主键检索数据
    let retrieve_data: Item = r.get().primary(3_u32)?.unwrap();
    println!("data id='3': {:?}", retrieve_data);
    // 迭代以 "red" 开始命名的所有项目
    for item in r.scan().secondary::<Item>(ItemKey::name)?.start_with("red") {
        println!("data name="red": {:?}", item);
    }
    
    // 删除数据(开启读写事务)
    let rw = db.rw_transaction()?;
    rw.remove(retrieve_data)?;
    rw.commit()?;
    
    Ok(())
}

上面的例子中使用create_in_memory创建的数据可存在数据持久化问题,当然你也可以存储在磁盘中。我们可以使用create和open的方式进行读写操作

pub fn create(&self, path: impl AsRef<Path>) -> Result<Database, DatabaseError>

如果文件不存在,或者是一个空文件,那么它将在其中初始化一个新的数据库。如果文件是一个有效的Redb数据库,那么它将被打开。否则,这个函数将返回一个错误。

另一个open方法只是打开这个数据文件。

native_db目前的状态

native_db 目前处于积极开发阶段。API 尚未稳定,未来可能会有变动。

本文使用 markdown.com.cn 排版