remdb - 嵌入式内存数据库
remdb是一个轻量级的嵌入式内存数据库,专为资源受限的嵌入式系统设计,支持no_std环境,具有可预测的内存使用和高性能。
主要功能
- 内存表存储:高效的内存表实现,支持插入、删除、查询和遍历操作
- 索引机制:
- 基于哈希的主键索引,提供O(1)的查询性能
- 多种辅助索引类型:
- Hash
- SortedArray
- BTree(默认)
- TTree
- SortedArray、BTree和TTree索引支持范围查询
- 事务支持:完整的ACID事务支持,包括:
- 原子性:事务要么全部提交,要么全部回滚
- 一致性:确保数据的完整性和正确性
- 隔离性:支持多种隔离级别(未提交读、提交读、可重复读、串行化)
- 持久性:通过预写日志(WAL)确保数据持久化
- 支持记录级锁(共享锁和排他锁)
- 支持事务日志和崩溃恢复
- 内存管理:
- 支持静态内存分配和动态内存分配
- 固定大小块内存池,支持高效的内存管理
- 动态内存分配器,支持运行时DDL操作
- 平台抽象层:支持POSIX和裸机环境
- 编译时配置:使用宏实现表和数据库的编译时配置,优化性能
- 低功耗模式:
- 支持进入和退出低功耗模式
- 低功耗模式下优化内存使用
- 减少事务日志写入频率,降低磁盘I/O
- 当记录数超过限制时,自动覆盖最旧的记录
- 增量快照:
- 同时支持完整快照和增量快照
- 增量快照只保存版本号变化的记录
- 通过仅存储变化数据,减少快照大小和保存时间
- 支持从增量快照恢复数据
- 版本管理机制,跟踪数据变化
- 兼容现有快照格式
- 基于Rust的编译期DDL解析与类型安全代码生成:
- 解析SQLite3语法兼容的DDL文件,生成类型安全的Rust代码
- 支持核心SQLite3 DDL语法:
CREATE TABLE、CREATE INDEX、列定义、PRIMARY KEY、NOT NULL、UNIQUE约束 - 支持在
CREATE INDEX语句中指定多种索引类型:HASH、SORTEDARRAY、BTREE(默认)、TTREE - 编译期执行语法和语义检查,提供清晰错误信息
- 生成强类型Rust结构体,字段名称、类型与DDL定义严格对应
- 生成静态表元数据,供数据库运行时使用
- 生成类型安全的API原型:
insert、get_by_id、update、delete函数 - 零运行时开销,使用过程宏实现
- 基于Rust过程宏的零成本DDL集成:
- 提供
MemdbTable过程宏,支持#[derive(MemdbTable)]语法 - 支持内联模式:直接在属性中编写DDL
- 支持文件模式:关联外部DDL文件
- 将SQL约束映射为Rust类型系统约束,编译期捕获错误
- 生成的代码
#[repr(C)],内存布局与手写代码完全一致
- 提供
- SQL查询支持:
- 支持标准SQL SELECT语句查询内存数据库的数据
- 支持基本查询、条件查询、排序和LIMIT限制
- 支持比较运算符:
=、!=、<、<=、>、>= - 提供友好的结果集接口,支持迭代访问和字段获取
- 运行时DDL配置API:
- 基于trait的DDL执行器设计,提供
DdlExecutortrait - 支持运行时创建表和索引
- 支持通过SQL语句执行DDL操作:
CREATE TABLE、CREATE INDEX - 支持多种索引类型配置
- 内存分配器抽象,支持自定义内存分配策略
- 基于trait的DDL执行器设计,提供
- SQL导出功能:
- 支持导出完整的DDL文件(表结构和索引定义)
- 支持导出表数据为SQL INSERT语句
- 输出兼容SQLite3语法,同时保留项目特定关键字
- 支持将导出结果写入文件或内存缓冲区
- 基于UDP的高可靠数据订阅与发布:
- 支持基于UDP协议的轻量级数据发布/订阅机制
- 对传输数据进行CRC校验,确保数据完整性
- 支持单播、广播和组播模式
- 提供subscribe(topic_id, callback)和publish(topic_id, data) API
- 支持基于NACK的重传机制,提高数据可靠性
- 支持心跳检测,自动清理不活跃的订阅者
- 每个主题支持不少于16个并发订阅者
- 支持不少于32个不同的数据主题
- 从调用publish API到数据进入网络栈的延迟小于100微秒
- 协议头开销小于载荷数据的10%
- 支持通配符订阅,允许使用主题模式匹配
- 高可用支持:
- 主从复制机制,确保数据一致性
- 自动故障检测和切换
- 心跳检测,监控节点状态
- 支持多种角色:主节点、从节点、自动模式
- 同步复制和异步复制两种模式
- 支持故障恢复和重新同步
- 提供高可用管理器,简化HA配置和管理
技术特点
- 零外部依赖:不依赖任何外部库,支持no_std环境
- 静态内存分配:可预测的内存使用,适合资源受限的嵌入式系统
- 编译时优化:通过宏实现编译时配置,减少运行时开销
- 多平台支持:支持POSIX和裸机环境
- 类型安全:使用Rust的类型系统确保数据安全
- 高效的同步机制:实现了自旋锁同步机制,适合多线程环境
快速开始
安装
将remdb添加到你的Cargo.toml文件中:
[]
= { = "./remdb", = false }
# 可选特性
# features = ["std", "posix"]
基本使用示例
extern crate alloc;
use Layout;
use *;
// 定义内存缓冲区
static mut DB_MEMORY: = ;
// 定义表结构
table!;
// 定义数据库配置
database!;
// 内存分配错误处理
!
### SQL查询示例
```rust
// 执行SQL查询获取所有用户
let result = db.sql_query.unwrap;
println!;
// 执行带条件的SQL查询
let result = db.sql_query.unwrap;
for row in result
// 执行带条件和排序的SQL查询
let result = db.sql_query.unwrap;
for row in result
低功耗模式使用示例
// 定义支持低功耗模式的数据库
database!;
// 初始化数据库
let db = init_global_db.unwrap;
// 进入低功耗模式
db.enter_low_power_mode.unwrap;
// 检查当前低功耗模式状态
let is_low_power = db.is_low_power_mode;
// 在低功耗模式下插入记录
for i in 0..150
// 退出低功耗模式
db.exit_low_power_mode.unwrap;
DDL宏使用示例
use MemdbTable;
// 使用内联DDL定义带索引的表
;
运行时DDL配置API示例
use ;
use ;
use NonNull;
// 简单的内存分配器实现
SQL导出功能示例
// 导出DDL(表结构和索引)到文件
let result = db.export_ddl;
if result.is_ok
// 导出表数据到文件
let result = db.export_data;
if result.is_ok
// 导出特定表的数据
// 参数:文件名,表名(可选,None表示导出所有表)
let result = db.export_data_with_table;
if result.is_ok
发布/订阅功能示例
use Duration;
use ;
// 创建发布/订阅配置
let config = PubSubConfig ;
// 创建发布/订阅实例
let mut pubsub = new.expect;
pubsub.init.expect;
// 定义订阅回调
let callback = ;
// 订阅主题
let subscription_id = pubsub.subscribe.expect;
// 发布数据
let msg = "Hello, PubSub!";
pubsub.publish.expect;
// 取消订阅
pubsub.unsubscribe.expect;
文件模式使用示例
use MemdbTable;
// 使用外部DDL文件定义带索引的表
;
// schema.ddl内容:
// CREATE TABLE user (
// id INTEGER PRIMARY KEY,
// name TEXT NOT NULL,
// email TEXT UNIQUE NOT NULL
// );
//
// CREATE INDEX idx_user_name ON user USING btree (name);
// CREATE INDEX idx_user_email ON user (email); -- 默认使用BTree
//
// CREATE TABLE product (
// id INTEGER PRIMARY KEY,
// name TEXT NOT NULL,
// price REAL NOT NULL,
// category TEXT
// );
//
// CREATE INDEX idx_product_price ON product USING ttree (price);
// CREATE INDEX idx_product_category ON product USING sortedarray (category);
平台支持
POSIX平台
启用POSIX平台支持:
= ["posix"]
裸机平台
启用裸机平台支持:
= ["baremetal"]
测试
运行单元测试
检查编译
在no_std环境下检查编译:
在baremetal环境下检查编译:
在baremetal环境下运行测试
由于测试框架依赖std库,直接运行cargo test在baremetal环境下会失败。但你可以通过以下步骤验证代码在baremetal环境下的正确性:
-
确保代码可以成功编译:
-
对于实际的baremetal硬件测试,你可能需要:
- 使用交叉编译工具链
- 编写针对目标硬件的测试代码
- 配置适当的链接脚本
- 使用烧录工具将可执行文件写入硬件
-
示例交叉编译命令(以ARM Cortex-M为例):
示例
查看examples目录下的示例代码:
basic_usage.rs:基本使用示例,展示表定义、插入、查询和事务操作low_power_mode.rs:低功耗模式示例,展示如何配置和使用低功耗模式incremental_snapshot.rs:增量快照示例,展示如何保存和恢复增量快照generate_snapshot.rs:快照生成示例,展示如何生成和使用快照sql_query.rs:SQL查询示例,展示如何使用SQL查询内存数据库ddl_example.rs:DDL示例,展示如何使用DDL宏定义表和索引ddl_full_example.rs:完整DDL示例,展示更复杂的DDL定义ddl_runtime_example.rs:运行时DDL配置示例,展示如何使用运行时DDL APIdescribe_table.rs:表结构描述示例,展示如何获取表的详细信息export_example.rs:导出功能示例,展示如何使用SQL导出功能ha_example.rs:高可用示例,展示如何使用高可用功能multiple_tables.rs:多表示例,展示如何使用多个表pubsub_example.rs:发布/订阅示例,展示如何使用基于UDP的高可靠数据订阅与发布功能pubsub_wildcard.rs:通配符发布/订阅示例,展示如何使用通配符订阅主题test_auto_increment.rs:自增字段示例,展示如何使用自增字段time_series.rs:时间序列示例,展示如何处理时间序列数据varchar_example.rs:VARCHAR类型示例,展示如何使用VARCHAR类型
项目结构
remdb/
├── src/
│ ├── lib.rs # 主库入口
│ ├── types.rs # 基本数据类型定义
│ ├── config.rs # 编译时配置宏
│ ├── table.rs # 内存表实现
│ ├── index.rs # 索引实现
│ ├── transaction.rs # 事务管理
│ ├── sql/
│ │ ├── mod.rs # SQL查询模块
│ │ ├── query_parser.rs # SQL查询解析器
│ │ ├── query_executor.rs # SQL查询执行器
│ │ └── result_set.rs # 结果集处理
│ ├── memory/
│ │ ├── allocator.rs # 静态内存分配器
│ │ ├── pool.rs # 内存池
│ │ └── mod.rs
│ ├── platform/
│ │ ├── mod.rs # 平台抽象层定义
│ │ ├── posix.rs # POSIX平台实现
│ │ └── baremetal.rs # 裸机平台实现
│ ├── ha/
│ │ ├── mod.rs # 高可用模块入口
│ │ ├── manager.rs # HA管理器实现
│ │ ├── replication.rs # 复制功能实现
│ │ ├── heartbeat.rs # 心跳检测实现
│ │ └── role.rs # 角色管理实现
│ └── pubsub/
│ ├── mod.rs # 发布/订阅模块入口
│ ├── protocol.rs # 协议帧定义与解析
│ ├── udp.rs # 跨平台UDP套接字封装
│ ├── subscriber.rs # 订阅者管理
│ ├── publisher.rs # 发布者管理
│ └── crc32.rs # CRC32校验实现
├── examples/
│ ├── basic_usage.rs # 基本使用示例
│ ├── low_power_mode.rs # 低功耗模式示例
│ ├── incremental_snapshot.rs # 增量快照示例
│ └── generate_snapshot.rs # 快照生成示例
├── tests/
│ ├── unit/
│ │ ├── memory_test.rs # 内存管理单元测试
│ │ └── table_test.rs # 表操作单元测试
├── Cargo.toml # 项目配置
├── Cargo.lock # 依赖锁定文件
├── PLAN.md # 项目计划
└── README.md # 项目说明文档
许可证
MIT许可证
贡献
欢迎提交问题和拉取请求!
注意事项
- remdb专为嵌入式系统设计,不适合大规模数据存储
- 在no_std环境下使用时,需要提供适当的内存分配器实现
- 请确保在使用前正确初始化内存分配器和平台抽象层
未来计划
- 支持更多的数据类型
- 优化内存使用
- 提供更多的索引类型
- 增加更多的示例和文档
- 实现更复杂的内存优化算法
- 添加低功耗模式下的性能监控
- 实现自适应低功耗模式,根据系统负载自动切换模式
- 完善运行时DDL配置API,支持完整的表和索引创建功能
- 支持DROP TABLE和ALTER TABLE语句
- 实现更灵活的内存分配策略
- 优化运行时DDL操作的性能
- 支持更复杂的索引配置选项