RegulusDB
RegulusDB 是一个用 Rust 编写的高性能嵌入式数据库,支持内存存储和持久化存储两种模式。它提供了类 SQL 的 API 查询构建器、B+ 树索引、事务支持以及 WAL(预写日志)+ 快照的持久化机制。
特性
- 多种数据类型: Null, Integer, Real, Text, Blob, Boolean, Date, Datetime
- 灵活的存储引擎:
MemoryEngine: 纯内存存储,适用于临时数据和缓存场景PersistedEngine: 持久化存储,支持崩溃恢复
- WAL + 快照持久化:
- 预写日志(WAL)确保数据持久性
- 定期快照(Snapshot)优化恢复速度
- 自动检查点(Checkpoint)机制(WAL > 10MB 时触发)
- 查询构建器:
- SELECT, UPDATE, DELETE 操作
- 比较操作符:=, !=, <, <=, >, >=, IN, LIKE
- 逻辑操作符:AND, OR, NOT
- 聚合函数:COUNT, SUM, AVG, MAX, MIN
- ORDER BY, LIMIT, OFFSET
- GROUP BY 和 HAVING 子句
- INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN
- DISTINCT 去重查询
- B+ 树索引:
- 单列索引和复合索引
- 唯一索引支持
- 自动索引选择优化查询
- 事务支持: ACID 语义的事务操作
- AUTO_INCREMENT 自增主键: 支持主键自增,允许显式覆盖,继承最大值模式
安装
将以下依赖添加到你的 Cargo.toml:
[]
= "0.1.0"
快速开始
内存模式
use ;
use Path;
持久化模式
use ;
use Path;
数据类型
| 类型 | 描述 | 示例 |
|---|---|---|
Null |
空值 | DbValue::Null |
Integer |
64 位有符号整数 | DbValue::integer(42) |
Real |
64 位浮点数 | DbValue::real(3.14) |
Text |
UTF-8 字符串 | DbValue::text("hello") |
Blob |
二进制数据 | DbValue::blob(vec![1, 2, 3]) |
Boolean |
布尔值 | DbValue::boolean(true) |
Date |
日期(自 1970-01-01 的天数) | DbValue::date(19000) |
Datetime |
日期时间(自 1970-01-01 的毫秒数) | DbValue::datetime(1609459200000) |
查询构建器
基本查询
// 查询所有用户
let all = db.query.execute?;
// 条件查询
let adults = db.query
.ge
.execute?;
// 多个条件
let result = db.query
.ge
.eq
.execute?;
比较操作符
db.query.eq; // =
db.query.ne; // !=
db.query.lt; // <
db.query.le; // <=
db.query.gt; // >
db.query.ge; // >=
db.query.in_list; // IN
db.query.contains; // LIKE (包含)
db.query.is_null; // IS NULL
db.query.is_not_null; // IS NOT NULL
逻辑操作符
use FilterExpr;
// OR 操作符:age > 18 OR status = 'active'
let results = db.query
.or
.execute?;
// NOT 操作符:简洁链式 API
// 简单条件:NOT (status = 'deleted')
let results = db.query
.not
.eq
.execute?;
// 复杂条件:使用 expr() 传入 FilterExpr
let results = db.query
.not
.expr
.execute?;
// 便捷方法
let results = db.query
.or_simple
.execute?;
let results = db.query
.not_simple
.execute?;
DISTINCT 去重
// 单列去重:查询不同的名字
let distinct_names = db.query
.select
.distinct
.execute?;
// 多列去重:查询不同的 (name, age) 组合
let distinct_rows = db.query
.select
.distinct
.execute?;
// 与 WHERE 和 ORDER BY 组合
let results = db.query
.select
.distinct
.gt
.order_by
.execute?;
排序和分页
// 按年龄降序排序
let sorted = db.query
.order_by
.execute?;
// 分页:每页 10 条,第 3 页
let page = db.query
.order_by
.limit
.offset // 跳过前 20 条
.execute?;
聚合函数
use Aggregate;
// COUNT
let count = db.query
.select_with_aggregates
.execute?;
// AVG
let avg_age = db.query
.select_with_aggregates
.execute?;
// SUM, MAX, MIN
let stats = db.query
.select_with_aggregates
.execute?;
GROUP BY 和 HAVING
use Aggregate;
// 按部门分组,统计每部门人数
let grouped = db.query
.select
.select_with_aggregates
.group_by
.execute?;
// HAVING 子句过滤分组
let high_departments = db.query
.select
.select_with_aggregates
.group_by
.having
.execute?;
JOIN 操作
// INNER JOIN
let results = db.query
.inner_join
.execute?;
// LEFT JOIN
let results = db.query
.left_join
.execute?;
// RIGHT JOIN
let results = db.query
.right_join
.execute?;
// FULL OUTER JOIN
let results = db.query
.full_outer_join
.execute?;
// 带字段选择和过滤
let results = db.query
.inner_join
.select
.gt
.order_by
.execute?;
更新和删除
UPDATE
// 更新单个字段
db.update
.eq
.set
.execute?;
// 更新多个字段
db.update
.eq
.set
.set
.execute?;
DELETE
// 删除单条
let deleted = db.delete
.eq
.execute?;
// 批量删除
let deleted = db.delete
.lt
.execute?;
事务中的更新和删除
在事务中,update 和 delete 使用函数式 API:
db.transaction?;
索引
创建索引
// 单列索引
db.create_index?;
// 复合索引
db.create_composite_index?;
// 唯一复合索引
db.create_unique_index?;
删除索引
// 删除单列索引
db.drop_index?;
// 删除复合索引
db.drop_composite_index?;
检查索引
if db.has_index
if db.has_composite_index
默认值
在创建表时可以为列指定默认值:
db.create_table?;
// 插入时只提供部分字段,其他字段使用默认值
db.insert?;
AUTO_INCREMENT 自增主键
为列添加 .auto_increment() 修饰器即可启用自增功能:
db.create_table?;
// 插入时不需要提供 id,自动生成
db.insert?;
db.insert?;
// id 会自动生成 (1, 2, 3, ...)
行为特性
- 自动生成:插入时未提供自增列的值时,自动生成下一个自增值
- 显式覆盖:允许用户显式指定自增列的值
- 继承最大值:用户显式提供值后,下一个自增值 = max(当前 next_id, 用户值) + 1
- 唯一性检查:自增主键自动具有唯一性约束,重复值会报错
- 不回滚:事务回滚后自增值不会重置(符合 MySQL/PostgreSQL 标准行为)
// 显式覆盖自增值
db.insert?;
// 下一条自增记录从 11 开始
db.insert?; // id 自动生成 11
事务
事务支持原子性操作和回滚功能:
// 基本事务
db.transaction?;
// 回滚示例
db.transaction?;
持久化机制
文件结构
RegulusDB 使用两个文件进行持久化:
| 文件 | 说明 |
|---|---|
data.rdb |
数据快照文件,包含完整的数据状态 |
data.rdb.wal |
预写日志文件,记录所有数据变更操作 |
恢复流程
- 加载
data.rdb快照到内存 - 重放
data.rdb.wal中的所有操作 - 数据恢复完成
检查点(Checkpoint)
- 自动触发: 当 WAL 文件大小超过 10MB 时自动触发
- 手动触发: 调用
engine.force_checkpoint()? - 过程: 保存快照 → 截断 WAL → 重置计数器
use ;
let mut engine = open?;
// 执行一些操作...
// 手动触发检查点
engine.force_checkpoint?;
// 检查是否需要检查点
if engine.wal_size > 0
测试
运行所有测试:
运行特定测试:
运行基准测试:
许可证
本项目采用 MIT 许可证。详见 LICENSE 文件。
致谢
RegulusDB 的设计受到了以下数据库的启发:
- SQLite: WAL 模式和 B+ 树索引
- Redis: RDB 快照和 AOF 日志
- PostgreSQL: MVCC 和事务处理