# 嵌入式内存数据库remdb需求
[TOC]
## ✅ 用户故事与验收条件
### **阶段一:最小可行产品(MVP)**
**核心存储引擎**
#### **US-101:轻量级内存表存储**
作为嵌入式开发者,我希望数据以紧凑的二进制格式存储在预分配的内存区域中,以便实现可预测的内存占用和快速访问。
**验收条件:**
1. 支持编译时配置表结构和容量,内存占用可精确计算
2. 提供简单API:insert、delete、get_by_id,无动态内存分配
3. 在STM32F4(168MHz)上,单记录操作平均延迟<100μs(无持久化)
4. 支持至少4种基本数据类型:整数、浮点、定长字符串、布尔、时间戳
**技术约束:**
- 不支持运行时修改表结构
- 最大表数量:32个
- 单表最大记录数:65535条
- 单记录最大大小:512字节
---
#### **US-102:简单索引机制**
作为查询优化者,我希望为关键字段创建索引以加速查询,同时控制内存开销。
**验收条件:**
1. 支持主键索引(哈希)和1个辅助索引(有序数组)
2. 索引内存占用不超过数据大小的50%
3. 通过索引的查询比全表扫描快10倍以上(选择性>1%时)
4. 索引维护与数据操作保持原子性
5. 提供索引使用统计
**技术约束:**
- 每表最多2个索引
- 不支持复合索引
- 索引键最大长度:64字节
---
#### **US-103:基本事务支持**
作为应用开发者,我希望简单的原子操作支持,保证多步骤操作的一致性。
**验收条件:**
1. 支持begin/commit/rollback语义
2. 事务内操作要么全部成功,要么全部回滚
3. 提供默认的读已提交隔离级别
4. 事务嵌套深度:1层(不支持嵌套事务)
5. 事务开销:空事务<50μs
---
**嵌入式适配**
#### **US-104:可配置的内存管理**
作为资源受限设备开发者,我希望根据设备内存情况灵活配置数据库内存使用。
**验收条件:**
1. 仅支持动态内存块两种分配策略
2. 可配置内存使用上限,接近上限时触发警告
3. 内存碎片率<5%(长期运行测试)
4. 支持无堆模式,所有内存预分配
5. 提供内存使用统计API
---
#### **US-105:平台抽象层**
作为跨平台开发者,我希望数据库核心不依赖特定操作系统,便于移植。
**验收条件:**
1. 抽象时间、同步、内存分配接口
2. 提供POSIX和裸机两种实现
3. 在Linux和FreeRTOS上通过功能测试
4. 平台相关代码<总代码的5%
5. 支持交叉编译到ARM Cortex-M
---
#### **US-106:零外部依赖设计**
作为裸机开发者,我希望数据库不依赖任何操作系统功能(除基本内存分配),以便在无OS环境中运行。
**验收条件:**
1. 无标准库依赖
2. 平台抽象层:提供时间、内存分配、文件I/O(可选)的接口
3. 编译选项:可禁用所有非必需功能(如日志、调试)
4. 代码体积:最小配置下<50KB(ARM Thumb2)
5. 支持无堆(heap-less)模式,全部静态分配
---
#### **US-107:WAL与检查点机制**
作为数据安全负责人,我希望通过写前日志和定期检查点保证数据持久化,以便在崩溃后快速恢复。
**验收条件:**
1. WAL格式:包含CRC校验、事务ID、操作类型、数据
2. 支持同步/异步日志模式:同步模式确保持久化,异步模式提高性能
3. 检查点:定时(可配置,默认60s)将内存状态完整保存
4. 恢复时先加载最新检查点,再重放后续WAL
5. 日志空间预分配,避免运行时扩展
**测试场景:**
- 模拟崩溃恢复,验证数据完整性
- 测量日志写入性能:同步模式<100μs/事务,异步模式<20μs/事务
- 验证大事务(>1MB)的日志正确处理
---
#### **US-108:日志压缩与轮转**
作为长期运行系统管理员,我希望WAL能自动压缩和轮转,以免日志文件无限增长占用存储空间。
**验收条件:**
1. 日志分段:每段固定大小(默认16MB),写满后创建新段
2. 压缩:旧日志段可压缩存储(gzip/LZ4可选)
3. 清理策略:保留最近N个检查点对应的日志(默认3)
4. 日志元数据:记录检查点位置,加速恢复定位
5. 磁盘空间监控:超过阈值(默认90%)时警告
**测试场景:**
- 连续运行24小时,验证日志不会无限增长
- 验证压缩后日志可正确解压用于恢复
- 模拟磁盘满的情况,验证优雅处理
------
#### **US-109:快速启动恢复**
作为嵌入式设备开发者,我希望数据库能在系统重启后毫秒级恢复,以便满足设备快速启动要求。
**验收条件:**
1. 恢复时间:100MB数据在SSD上恢复时间<500ms
2. 恢复期间内存使用不超过运行时的120%
3. 支持恢复进度回调,可显示进度百分比
4. 恢复过程可中断,中断后数据仍处于一致状态
5. 提供恢复统计:读取字节数、应用事务数、耗时
**测试场景:**
- 不同数据量下的恢复时间测试(10MB-1GB)
- 模拟恢复中途断电,验证恢复可继续
- 恢复过程中并发访问尝试应被阻塞
#### **US-110:核心需求:零拷贝访问**
作为 需要极致性能的应用程序开发者,我希望 数据库在执行查询和返回结果时,能够避免在数据库内部缓冲区与应用程序缓冲区之间进行任何不必要的数据拷贝,以便于 实现微秒级甚至纳秒级的低延迟数据访问,并让CPU的计算资源更多地用于业务逻辑而非数据搬运。
**详细规格与验收条件**
1. 读取路径零拷贝
· 需求描述:当应用程序通过API(如根据主键或索引查询单条记录)请求数据时,数据库应直接返回指向其内部内存存储位置的指针或引用,而非将数据复制到新的缓冲区。
· 验收条件:
· 查询返回的“行”或“记录”对象,本质上是一个内存视图或引用。
· 在返回此引用期间,数据库的内存管理机制(如垃圾回收、压缩)必须保证该内存区域的稳定性,不会被移动或释放。
· 性能指标:点查询操作(如 get_by_id)的延迟应接近纯内存指针解引用的开销,与数据大小无关。
2. 写入/更新路径的高效拷贝
· 需求描述:写入操作通常难以做到“零拷贝”,因为输入数据来自外部。但需求应优化为 “单次拷贝” ,即数据从应用程序传入后,仅被拷贝一次即到达其最终的存储位置,并在此过程中完成序列化(如果必需)。
· 验收条件:
· 提供接收连续内存布局(如C结构体、Rust的 #[repr(C)] 结构体)的写入接口。
· 写入时,数据库应能通过 memcpy 或类似机制,一次性地将数据从用户缓冲区搬运到其预分配好的存储槽位中。
· 避免任何中间格式的转换或多次拷贝。
3. 扫描/迭代的零拷贝
· 需求描述:当进行全表扫描或范围查询时,数据库应提供能够原地迭代的游标(Cursor)机制。该游标直接遍历数据库内部的存储页或连续内存块,逐条返回记录的引用。
· 验收条件:
· 迭代器每次 next() 调用返回一个指向当前记录的引用,而非拷贝。
· 支持在迭代过程中安全地更新或删除当前记录(需定义明确语义,如是否立即生效或影响后续迭代)。
· 验收条件:
· 在传输大型结果集(如批量查询、流式响应)时,CPU使用率显著降低。
** 必须考虑的关联约束与挑战 **
零拷贝带来了性能的极大提升,但也引入了复杂性和新的要求,必须与其他需求协同设计:
1. 内存管理:
· 必须与 US-104 静态内存池管理深度集成。使用预分配的、固定大小的内存池或对象池是实现零拷贝的基础。这确保了记录在内存中的位置长期稳定,指针不会失效。
· 当需要压缩或整理内存时(如应对碎片),需要采用写时复制或影子分页技术,并在后台平滑地迁移数据,同时更新所有活动的引用。
2. 并发控制与事务:
· 必须与 US-205(ACID事务) 集成,保证在事务存活期间必须该版本的数据被“钉住”(pin),不能被垃圾回收。
· 需要高效的版本生命周期管理和垃圾回收机制,确保在无事务引用时能及时回收旧版本数据。
3. 数据安全与隔离:
· 直接返回内部指针意味着应用程序可能意外修改数据库内部数据。解决方案包括:
· 返回只读视图(Rust的 &T 或 &[u8])。
· 如果需要修改,提供专门的 update API,在内部处理拷贝和版本更新。
4. 序列化/反序列化成本消除:
· 这是零拷贝的最大收益点之一。数据库的内部存储格式应与应用程序的内存中的对象格式尽可能一致或兼容。
· 这与你的 US-210(编译期DDL生成) 完美契合:生成的Rust结构体 #[repr(C)] 可以直接映射为数据库的存储格式,访问时无需任何解析或转换。
** 总结:零拷贝的本质 **
零拷贝访问需求的本质,是让内存数据库从“数据存储服务”向“内存管理服务”演进。它不再仅仅负责安全地存放数据,更要高效地组织内存,使应用程序能像使用自己的堆内存一样,直接、安全、并发地访问数据库中的数据。这需要数据库在存储布局、并发控制、内存管理和API设计上进行高度协同的、精细化的设计,是实现百万级QPS目标(US-505)的基石技术之一。
---
### **阶段二:核心优化**
**持久化与可靠性**
#### **US-201:快照式持久化**
作为数据安全负责人,我希望定期将内存状态保存到非易失存储,以便在重启后恢复。
**验收条件:**
1. 支持手动触发和定时自动快照(可配置间隔)
2. 快照保存时间:1MB数据<500ms(SPI Flash)
3. 恢复时间:1MB数据<800ms
4. 快照存储格式紧凑,支持CRC32校验
5. 支持增量快照以减小存储开销(可选)
**技术约束:**
- 快照期间阻塞写操作,读操作可继续
- 不支持事务日志,仅支持快照恢复到最后一致状态
---
#### **US-202:并发访问优化**
作为多任务应用开发者,我希望数据库支持安全的并发访问,避免数据竞争。
**验收条件:**
1. 支持读写锁机制,读多写少场景下性能优化
2. 提供简单的乐观锁(版本号)机制
3. 死锁检测超时:默认100ms
4. 8个并发读线程时,吞吐量下降<30%
5. 2个并发写线程时,数据一致性100%保证
---
#### **US-203:内存保护机制**
作为安全敏感应用开发者,我希望设置内存使用硬上限,并在接近上限时触发回调,以便防止内存溢出。
**验收条件:**
1. 硬上限配置:全局内存上限和表级内存上限
2. 水位线警告:80%时警告回调,95%时严重警告
3. 超出上限处理:拒绝新插入或触发清理策略
4. 内存统计:实时监控各组件内存使用
5. 支持内存压力测试,验证上限有效性
---
#### **US-204:CPU缓存优化**
作为性能敏感应用开发者,我希望数据结构和访问模式优化CPU缓存命中率,以便减少内存访问延迟。
**验收条件:**
1. 数据布局:热字段集中存储,冷字段分离
2. 缓存行对齐:关键数据结构64字节对齐
3. 预取提示:对顺序扫描提供软件预取
4. 缓存感知算法:B+树节点大小为缓存行倍数
5. 性能提升:相比未优化版本,L1缓存命中率提升>20%
---
#### **US-205:嵌入式环境下的ACID事务支持**
作为嵌入式关键业务应用(如金融终端、工业控制)的开发者,我希望内存数据库提供完整的ACID事务支持,以便在资源受限的硬件上,安全、可靠地执行复杂的数据操作序列,确保数据的一致性和可靠性。
**验收条件:**
原子性实现
- 提供 begin(), commit(), rollback() 基础API。
- 事务内的所有数据修改(增、删、改)必须作为一个不可分割的整体:提交时全部生效,回滚时全部撤销,无中间状态。
- 实现写前日志或影子页/多版本机制来支持原子回滚。在事务过程中,原始数据必须被保护,直至提交。
一致性保证
- 事务必须将数据库从一个一致状态转换为另一个一致状态。
- 支持在数据模式中定义的基础约束(如主键唯一性、非空字段),并在事务提交时进行验证,违反约束将导致事务中止。
- 提供可选的应用程序定义的一致性检查回调函数。
隔离性控制
- 默认提供快照隔离 级别:每个事务开始时获取一个数据快照,在其整个执行过程中都基于此快照读取,避免脏读、不可重复读。
- 通过多版本并发控制 实现:数据修改创建新版本,旧版本根据事务存活情况由垃圾回收机制清理。
- 写操作(增、删、改)使用行级悲观锁或乐观锁(带冲突检测与重试)来保证序列化写入,防止丢失更新。
持久性策略
- 事务提交后,其修改必须得到持久化保证。
- 提供两种策略,由应用在初始化时选择:
- 全持久模式:事务提交时,相关修改必须同步写入持久化存储(如遵守US-107的WAL)。
- 延迟持久模式:事务提交立即在内存中生效,但允许将持久化操作异步批量执行,此模式下需提供 tx_sync() API 手动触发刷盘。
性能与资源约束
- 单次事务(含开始、若干操作、提交)的典型开销(空事务)应低于 50微秒(在100MHz级嵌入式CPU上)。
- 事务机制引入的内存开销(如版本存储、锁结构)不得超过数据库总内存占用的 15%。
- 支持至少 8个 并发活动事务。
测试场景:
原子性与回滚测试:
- 执行一个插入多条记录的事务,在提交前模拟失败并调用回滚,验证所有插入痕迹被完全清除。
- 测试嵌套操作(如插入后更新再删除同一记录)在回滚后的一致性。
隔离性与并发测试:
- 启动两个并发事务:事务A读取一行数据,事务B修改并提交该行数据。验证事务A的读取结果不受事务B影响(快照隔离)。
- 启动两个并发写事务尝试修改同一行数据,验证只有一个成功(通过锁或冲突检测机制)。
性能与压力测试:
- 创建16个线程,每个线程循环执行包含随机读写的小事务,持续运行1分钟,统计每秒完成的事务数,并检查最终数据一致性。
- 监控在长时间运行并发事务后,内存中版本链的增长情况,验证垃圾回收机制的有效性,防止内存无限增长。
**查询功能**
#### **US-206:条件查询引擎**
作为应用开发者,我希望通过条件表达式查询数据,而不仅仅是主键查询。
**验收条件:**
1. 支持简单的比较条件:=、!=、<、>、≤、≥
2. 支持AND操作,最多3个条件组合
3. 支持通过索引的查询自动优化
4. 查询执行计划可输出(调试版本)
5. 全表扫描性能:1000条记录<1ms
---
#### **US-207:Qt快照查看工具emdbui**
作为开发人员,我希望有一个图形化工具来查看remdb快照文件,以便直观地了解数据库状态和数据内容。
**验收条件:**
1. 支持打开和解析remdb快照文件
2. 显示数据库表的基本信息(表名、记录数、字段信息等)
3. 支持按表分页查看表数据
4. 提供数据导出功能(CSV格式)
5. 支持搜索和过滤记录
6. 界面友好,操作简单
7. 支持Windows/Linux跨平台运行
**技术约束:**
- 基于Qt 5.14.2框架开发
- 无其他外部依赖
- 支持查看至少10000条记录的表
- 响应时间:打开1MB快照文件<2秒
---
**外部接口**
#### **US-208:基于UDP的高可靠数据订阅与发布**
作为嵌入式实时系统开发者,我希望数据库内置一个基于UDP协议的轻量级数据发布/订阅机制,并对传输数据进行CRC校验,以便在局域网内实现高效、可靠的数据广播或组播,满足传感器数据分发、多节点状态同步等场景的需求。
**验收条件:**
协议与接口设计:
定义二进制协议帧,包含:帧头(魔术字、版本、类型)、序列号、主题ID、数据长度、CRC32校验和、载荷数据。
提供API:subscribe(topic_id, callback)用于订阅主题,publish(topic_id, data)用于发布数据。
支持单播、广播和组播(Multicast)模式,可通过配置切换。
**核心功能要求:**
- 数据完整性保障:每个发出的UDP数据包都必须包含基于载荷计算出的CRC32校验和。接收方必须验证校验和,丢弃无效包,并可选择性地请求重传(基于序列号)。
- 订阅管理:服务端维护主题-订阅者列表的动态映射。支持订阅者的动态加入与离开。
- 极低延迟发布:从调用publish API到数据进入网络栈的延迟小于100微秒(在100MHz级嵌入式CPU上)。
- 资源预配置:内存池、套接字缓冲区等资源均在初始化时静态分配,避免运行时动态内存分配。
**性能与资源约束:**
- 支持不少于32个不同的数据主题。
- 每个主题支持不少于16个并发订阅者。
- 在以太网(100Mbps)环境下,端到端(发布者到订阅者)数据延迟99分位线小于5ms。
- 协议头开销小于载荷数据的10%(针对小数据包优化)。
- 可靠性增强:
- 提供可选的、简单的否定确认(NACK)与重传机制,以应对偶发的UDP丢包。
- 支持“心跳”包,用于检测订阅者的存活状态,并清理无效订阅。
**测试场景:**
功能正确性测试:
- 验证一个发布者向一个主题发布带CRC的数据,多个订阅者能正确接收并验证通过。
- 验证发送故意损坏(CRC错误)的数据包会被订阅者静默丢弃。
- 验证动态订阅与取消订阅功能。
性能与资源测试:
- 在回环接口和真实交叉网线上,测试发布100字节载荷数据,达到1000 Hz发布频率时,CPU使用率不超过15%。
- 测量从publish调用到订阅者回调函数触发的端到端延迟分布。
- 监控在长时间运行下,内存池无泄漏、无碎片。
- 网络容错测试:
- 在存在网络抖动和丢包(可通过工具模拟)的环境中,测试启用重传机制后的数据最终交付成功率大于99.99%。
- 模拟订阅者意外宕机,验证发布者的“心跳”机制能正确清理其订阅状态。
---
#### **US-210:基于Rust过程宏的编译期DDL解析与零成本类型安全代码生成**
**作为** 使用Rust的嵌入式开发者,**我希望** 通过直观的Rust属性宏(`#[derive]` 风格)来声明数据库模式,支持内联和文件两种方式解析SQLite3语法兼容的DDL,并在编译期自动生成类型安全的Rust数据结构和数据库操作API,**以便于** 在获得SQL声明式便利的同时,实现与手动编写Rust结构体同等的运行时性能与内存效率。
**验收条件:**
1. **声明式API设计**
- 提供 `MemdbTable` 过程宏。用户通过在结构体上标注 `#[derive(MemdbTable)]` 和 `#[memdb_schema]` 属性来定义表。
- 支持两种模式:
- **内联模式**:直接在属性中编写DDL。
rust
```
#[derive(MemdbTable)]
#[memdb_schema(ddl = "CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT NOT NULL);")]
struct UserTable; // 此结构体为标记,其名称`UserTable`可用于命名空间
```
- **文件模式**:关联外部的DDL文件。
rust
```
#[derive(MemdbTable)]
#[memdb_schema(file = "schema.ddl")] // 文件内容可包含多个CREATE TABLE语句
struct MyDatabase;
```
2. **DDL解析与验证**
- 能够解析核心SQLite3 DDL语法:`CREATE TABLE`、列定义(`INTEGER`、`TEXT`、`REAL`、`BOOLEAN`)、`PRIMARY KEY`、`NOT NULL`、`UNIQUE`约束。不支持`BLOB`。
- 在编译期执行语法和语义检查(如重复表名、未知数据类型),并提供清晰错误信息,导致编译失败。
- 支持通过 `//` 或 `/* */` 注释。
3. **编译期代码生成**
- 为DDL中的**每张表**生成一个对应的Rust实体结构体(如 `User`),其字段名和类型(`i64`, `String`, `Vec<u8>` 等)与DDL严格映射。
- 生成一个**标记结构体的关联模块**,其中包含:
- 生成的实体结构体(如 `User`)。
- 类型安全的**表操作Trait约束**和**函数原型**(如 `fn insert(&self, entity: User) -> Result<()>`)。
- 静态的**表元数据**(表名、列信息、主键等),以 `const` 或 `static` 形式存储。
- 所有生成的代码必须通过 `rustc` 编译和 `clippy` 默认检查。
4. **类型安全与约束映射**
- 将SQL约束映射为Rust类型系统约束:
- `NOT NULL` -> 非 `Option` 类型(如 `String`)。
- 可为空的列 -> `Option<T>` 类型(如 `Option<String>`)。
- `PRIMARY KEY` 和 `UNIQUE` 约束信息存入元数据,供事务引擎用于运行时检查。
- 为每个表生成唯一的 `TableId` 类型,用于在编译期区分不同的表。
5. **零开销与编译时保障**
- **零运行时解析**:数据库引擎在启动时无需读取或解析DDL文件,所有结构信息已编译在二进制中。
- **生成的代码必须不依赖任何运行时反射**,所有类型信息在编译时确定。
- **内存布局等同手写代码**:生成的实体结构体 `#[repr(C)]`,其内存布局与手写结构体完全一致,无任何额外填充或隐藏字段。
- **编译时错误报告**:DDL语法错误、类型不支持的语义错误必须在编译时报告,并尽可能指向DDL中的行号和列号。
6. **性能与资源约束**
- 过程宏的执行时间:对于包含50张表的DDL,宏展开增加的编译时间应 **< 2秒**。
- 生成的代码量:每张表生成的额外代码(除实体结构体外)应 **< 5KB**(Rust源码体积)。
- 生成的代码本身**不得引入额外的内存开销**,数据结构的内存布局应与手动编写的等效Rust结构体完全一致。
- 支持至少 **128张表** 的定义。
**测试场景:**
1. **功能与集成测试**
- **内联模式测试**:编写一个包含2-3张表的内联DDL,验证宏能正确展开,生成的代码可编译,且实体结构体字段正确。
- **文件模式测试**:使用一个包含复杂外键(暂存为注释)和索引定义的外部DDL文件,验证宏能读取文件并正确生成所有表结构。
- **约束映射测试**:创建一个包含 `NOT NULL`、`UNIQUE` 和各种SQL类型的表,验证生成的Rust结构体字段类型是否符合预期(如 `NOT NULL TEXT` -> `String`, 可空 `INTEGER` -> `Option<i64>`)。
- 编写一个小型测试程序,使用生成的API插入数据,并通过数据库核心引擎验证数据能被正确存储和检索。
2. **编译期错误测试**
- **语法错误**:提供 `CREATE TBL ...` (错误关键字)的DDL,验证编译器会输出清晰的错误,并指向DDL字符串或文件中的具体位置。
- **语义错误**:定义重复的列名,验证编译会失败并提示 "duplicate column name 'x'"。
3. **性能与开销验证**
- **编译时间基准**:在一个干净的项目中,测量添加该宏依赖前后的 `cargo build --release` 编译时间差。
- **内存布局对比**:使用 `std::mem::size_of` 和 `align_of` 对比生成的 `User` 结构体与手动编写的、字段完全相同的结构体,确认两者大小和对齐方式一致。
- **代码膨胀测试**:检查最终二进制中,与生成的128张表元数据相关的只读数据(`.rodata`段)大小,评估其合理性。
- **性能基准测试**:对比使用生成的API与使用动态SQL字符串接口执行相同操作(如插入10000条记录)的性能差异,验证无抽象惩罚。
---
#### US-211:增量快照功能
作为数据安全负责人,我希望只保存自上次快照以来的变化数据,以便减少快照存储开销和生成时间,同时保持数据恢复能力。
**验收条件:**
1. 支持在全量快照基础上生成增量快照
2. 增量快照大小不超过全量快照的30%(数据变化率<20%时)
3. 增量快照生成时间比全量快照快50%以上
4. 支持从最新全量快照+所有后续增量快照恢复
5. 增量快照包含变化数据的CRC32校验
6. 支持配置最大增量快照数量,自动清理旧快照
7. 提供快照链完整性检查工具
**技术约束:**
- 仅支持基于时间点的增量快照
- 最大增量快照链长度:16个
- 增量快照与全量快照使用相同的存储接口
- 不支持跨设备的增量快照生成
---
#### **US-212:高级索引类型支持**
作为查询优化者,我希望数据库支持多种索引类型,以便根据不同查询场景选择最优索引,提高查询性能。
**验收条件:**
1. 支持B-Tree索引(适用于范围查询和顺序访问)
2. 支持T-Tree索引(适用于频繁更新的场景)
3. 索引类型可在编译时配置
4. B-Tree索引在范围查询时比有序数组索引快5倍以上(数据量>1000条)
5. T-Tree索引在随机更新场景下比B-Tree快3倍以上
6. 新索引类型的内存开销不超过数据大小的50%
7. 索引维护与数据操作保持原子性
8. 提供索引类型性能对比工具
**技术约束:**
- 每表最多支持3个索引(包括主键索引)
- 索引键最大长度:64字节
- 支持的索引类型:哈希(主键)、有序数组、B-Tree、T-Tree
---
#### **US-213:多版本并发控制(MVCC)引擎**
**作为** 需要高并发读写能力的嵌入式应用开发者,**我希望** 数据库内核实现高效的多版本并发控制机制,**以便于** 读操作与写操作互不阻塞,在保证快照隔离级别的事务一致性的同时,提供接近无锁的读取性能,满足实时系统中的高并发数据访问需求。
**验收条件:**
1. **版本化存储与快照读**
* 任何数据行(记录)在被更新或删除时,必须保留其旧版本,并为该版本标记一个唯一的、全局递增的**创建事务ID**和**删除事务ID**。
* 当某个事务执行查询时,数据库需根据该事务启动时获取的**快照版本号**,自动筛选出对该事务可见的数据版本。可见性规则为:行的`创建事务ID` ≤ 事务快照号,且 (`删除事务ID` 为未提交 或 `删除事务ID` > 事务快照号)。
* **读取永不阻塞写入**:任何查询操作都无需获取行锁,而是直接访问已提交的、可见的数据版本。
2. **高效的版本存储与垃圾回收**
* 同一行的多个版本应以紧凑的**版本链**形式存储(如单向链表),链头为最新版本,以加速最新版本的访问。
* 必须实现**自动垃圾回收**机制,定期清理不再被任何活跃事务快照所引用的旧版本数据,防止内存无限增长。
* 垃圾回收必须是**非阻塞**和**增量式**的,其执行不应导致前端事务暂停。内存回收开销需限制在总事务时间的 **5%** 以内。
3. **写入并发控制与冲突解决**
* 写入操作(INSERT, UPDATE, DELETE)必须检测**写-写冲突**。当两个事务尝试修改同一行数据时,应通过行级锁或乐观锁(如检查版本号)来保证序列化。
* 提供**可配置的冲突解决策略**:支持乐观并发控制(先提交者胜出,后提交者事务回滚)或悲观并发控制(获取行锁)。
* 在32核模拟环境下,读写混合负载的吞吐量下降应低于**纯锁模型的30%**。
4. **与核心架构的深度集成**
* **与事务集成**:为每个事务自动分配单调递增的**唯一事务ID**,作为版本标记和快照依据。
* **与内存管理集成**:版本数据必须从**预分配的内存池**中分配,其生命周期由垃圾回收器管理,确保内存使用的确定性和无碎片化。
* **与持久化集成**:WAL日志必须记录足以重建完整版本链的信息,确保崩溃恢复后MVCC状态的一致性。
5. **资源与性能约束**
* MVCC元数据(事务ID、版本指针)带来的单行存储开销应 **< 16字节**。
* 单次点查询因MVCC版本链遍历引入的额外延迟应 **< 100纳秒**(在链长小于5时)。
* 支持维护至少 **1024个** 并发活跃事务的快照视图。
**测试场景:**
1. **快照隔离正确性测试**:
* 事务A读取一行数据,事务B修改并提交该行数据后,再次在事务A内读取,验证两次结果一致(不可重复读被防止)。
* 启动一个长时间运行的事务,在其执行期间,验证它能持续看到事务开始时的数据快照,不受后续已提交事务的影响。
2. **并发性能与压力测试**:
* 模拟典型读写混合负载(如80%读,20%写),在16个并发线程下持续运行,验证吞吐量和高位延迟(P99)符合预期,且无内存无限增长。
* 在持续高压力写入下,验证垃圾回收机制能有效工作,版本链平均长度被稳定控制在 **< 10**。
3. **恢复与完整性测试**:
* 在MVCC运行期间模拟数据库崩溃,重启后验证:1) 所有已提交事务的数据可见;2) 未提交事务的数据被完全回滚;3) 版本链状态完整。
---
🧠 设计要点说明
此MVCC设计(US-213)是你整个ACID事务(US-205)的**核心子模块和高级实现**,它直接解决了并发下的隔离性问题。
1. **与零拷贝的关系**:MVCC是实现**零拷贝读取**的理想伙伴。只读事务可以直接获得指向某个稳定版本的指针,无需加锁或拷贝。但这也要求版本在事务存活期内必须被“钉住”,这需要与**确定性内存管理(US-202)** 和**垃圾回收**精细协作。
2. **与编译期DDL的关系**:通过 **US-210 过程宏**生成的强类型结构体,可以直接作为版本存储的单元,使得版本化的数据访问依然是类型安全和高效的。
3. **嵌入式优化**:与通用数据库不同,此设计强调**预分配**和**确定性的GC**,以避免在资源受限环境下由垃圾回收引起的不确定延迟。版本链长度和事务快照数量都有明确上限,符合嵌入式设计哲学。
**实现提示**:在Rust中,可以利用 `Arc` 或自定义的引用计数结构来管理版本的生命周期,利用 `Pin` 确保版本内存位置稳定,以安全地支持零拷贝引用。垃圾回收器可以是一个后台任务,基于全局活跃事务快照列表来扫描和回收可释放的版本。
---
#### **US-214:确定性容量与性能指标**
**作为** 嵌入式系统集成工程师,**我希望** 数据库在编译和初始化时,能根据目标环境(`no_std` 或 `POSIX`)锁定一组明确的、可验证的性能与容量上限指标,**以便于** 我在设计硬件选型、内存规划和部署架构时,能有精确的数据依据,确保数据库在产品的整个生命周期内稳定运行,不出现资源耗尽或性能不达标的风险。
**验收条件:**
1. **环境分化的核心吞吐与容量指标**
* 数据库必须提供两个核心的特性开关(`no_std` 和 `POSIX`),编译时选定,运行时不可更改。
* 在 `no_std` 特性下,数据库必须满足:
* 混合读写负载(读写比 9:1)下,**每秒查询率(QPS)不低于 10万**。
* 单表支持的最大列数 **≤ 32**。
* 支持创建的最大表数量 **≤ 64**。
* 最大向量维度 **≤ 4096**。
* 向量索引数量 **≤ 1024**。
* 支持向量索引算法配置,默认使用**近似最近邻(ANN)算法**以优化内存占用和查询性能。
* 在 `POSIX` 特性下,数据库必须满足:
* 混合读写负载(读写比 9:1)下,**每秒查询率(QPS)不低于 50万**。
* 对单表列数和数据库总表数**不做编译期限制**,仅受运行时可用内存约束。
* 最大向量维度 **≤ 4096**。
* 向量索引数量 **≤ 1024**。
* 支持向量索引算法配置,默认使用**近似最近邻(ANN)算法**以优化内存占用和查询性能。
2. **持久化子系统参数指引**
* 基于核心QPS指标和典型负载(写入操作占10%,平均WAL记录256字节),数据库应提供默认的持久化配置,并允许用户在初始化时调整:
* **WAL日志段大小**:`no_std` 环境默认 **64MB**;`POSIX` 环境默认 **512MB**。必须支持日志轮转。
* **检查点周期**:`no_std` 环境默认 **60秒**;`POSIX` 环境默认 **300秒**。
* 这些默认配置的目标是:在对应环境下,**恢复时间(RTO)** 应分别少于 **5秒**(`no_std`)和 **30秒**(`POSIX`)。
3. **关键性能与可靠性保障指标**
* 无论何种环境,数据库在持续压力测试下必须同时满足:
* **写入延迟**:99% 的请求延迟(P99) **< 1ms**。
* **读取延迟**:99% 的请求延迟(P99) **< 500μs**。
* **向量相似度搜索延迟**:99% 的请求延迟(P99) **< 1ms**(针对1000个向量的数据集)。
* **数据持久性(RPO)**:在启用同步WAL模式下,必须为 **0**(崩溃后无数据丢失)。
* **可用性**:在模拟的年度运行周期测试中,系统可用性不低于 **99.9%**。
4. **资源占用上限指标**
* 在 `no_std` 环境下:
* 数据库核心组件(数据、索引、事务上下文等)的**最大内存占用必须静态分配,且默认总值不得超过 64MB**。此限制必须在编译期通过配置计算得出,并在启动时完成分配。
* 提供**向量功能的单独内存配置选项**,允许用户根据实际向量需求调整向量相关内存分配,最高可配置为核心内存的2倍(即默认最高128MB)。
* 支持**向量数据压缩选项**,提供至少2种压缩算法(如标量量化、乘积量化)供用户选择,以减少内存占用和持久化开销。
* 在 `POSIX` 环境下:
* 数据库应提供清晰的内存使用监控接口,并支持设置软性上限(如1GB),在接近上限时进行告警或流量控制。
* 支持**向量功能的单独内存配置选项**,允许用户根据实际向量需求调整向量相关内存分配。
* 支持**向量数据压缩选项**,提供至少2种压缩算法(如标量量化、乘积量化)供用户选择,以减少内存占用和持久化开销。
**验收测试场景:**
1. **基准性能验证**:
* 使用标准的键值存储性能测试工具(如改造后的YCSB),运行读写比为9:1的负载,持续至少5分钟,验证平均QPS和P99延迟达标。
* 在 `no_std` 环境下,需验证在达到32张表、每表12列的配置极限时,系统功能正常,性能无显著衰减。
* 验证向量维度4096下的相似度搜索性能,确保延迟达标。
* 验证不同向量索引算法(包括ANN算法)的性能表现,确保内存占用和查询性能符合预期。
2. **恢复与持久化验证**:
* 在持续达到50%目标QPS的压力下运行,随机触发模拟崩溃。测量从重启到完全恢复服务的时间,验证其小于规定的RTO目标。
* 崩溃恢复后,校验数据完整性,必须确保RPO目标达成。
* 验证包含压缩向量数据的持久化和恢复性能,确保符合预期。
3. **容量与稳定性边界测试**:
* **`no_std` 测试**:
* 运行直到核心内存占用接近64MB上限,验证系统行为符合预期(如优雅拒绝新写入),且无内存越界。
* 验证向量功能单独内存配置选项的有效性,确保向量内存分配正确。
* 验证向量数据压缩选项的效果,测量压缩前后的内存占用差异。
* **`POSIX` 长稳测试**:
* 以80%的最大目标QPS持续运行24小时,监控内存、CPU使用率,要求无资源泄漏,且性能曲线平稳。
* 验证向量功能在长时间运行下的稳定性和性能表现。
4. **向量功能专项测试**:
* 测试向量维度4096时的内存使用情况,验证内存配置的合理性。
* 测试1024个向量索引的创建和查询性能,验证系统稳定性。
* 比较不同向量压缩算法的性能和压缩率,验证压缩选项的有效性。
---
🧠 设计关联与说明
此需求是对之前所有技术设计的**定量化约束和验收标准**,特别是针对向量功能的确定性容量和性能指标。
* **与US-104(内存管理)的关联**:
* `no_std` 下的64MB核心内存上限是静态内存池设计的直接输入。
* 向量功能的单独内存配置选项扩展了内存管理的灵活性,允许用户根据实际需求调整。
* `POSIX` 下的内存监控是动态管理的前提。
* **与US-107(WAL与检查点)的关联**:
* 本需求中推导出的WAL大小和检查点周期,应作为US-107实现的**默认配置和性能验证基准**。
* 向量数据的压缩存储需与WAL机制协同设计,确保压缩数据的高效持久化和恢复。
* **与US-103(事务)和US-505(百万QPS)的关联**:
* 本需求的性能指标是这些高级功能的**阶段性、环境差异化的具体目标**。
* 向量操作的性能指标需与整体QPS目标协同考虑。
* **指标的可配置性**:
* 虽然规定了默认值和目标,但WAL大小、检查点周期、内存上限、向量算法选择和压缩选项等关键参数必须保留为**可配置项**,允许高级用户根据实际硬件和负载特征进行调优。
这个需求将性能愿景转化为了**可测量、可验证的工程契约**,特别是针对向量功能的确定性表现,是确保 `remdb` 在不同目标环境中都能交付稳定可靠表现的核心。
---
#### **US-215:动态表结构管理支持**
**作为** 嵌入式应用开发者,**我希望** 数据库在运行时支持有限的表结构修改操作,包括删除表(DROP TABLE)和修改表(ALTER TABLE),**以便于** 在应用生命周期中能够适应数据结构的变化需求,而无需重启系统或重新编译数据库。
---
**验收条件:**
**1. DROP TABLE 功能**
- 支持 `DROP TABLE [IF EXISTS] table_name` 语法
- 删除表时自动清理:
- 所有数据记录
- 所有关联的索引(主键索引和辅助索引)
- 表级统计信息
- 事务上下文中的相关资源
- 内存立即回收:表占用的内存应返回内存池,可供其他表重用
- 并发安全:当有活跃事务正在访问该表时,删除操作应被阻塞或优雅拒绝
- 持久化支持:如果启用了WAL,删除操作应记入日志,确保崩溃恢复后表状态一致
- 提供删除前的安全检查选项(如检查外键依赖,但注意当前设计无外键)
**示例语法支持:**
```sql
-- 基本删除
DROP TABLE sensor_data;
-- 安全删除(表不存在时不报错)
DROP TABLE IF EXISTS old_sensor_data;
```
**2. ALTER TABLE 基本功能**
支持以下常用的表结构修改操作:
**a) 增加列**
```sql
ALTER TABLE sensor_data ADD COLUMN status INTEGER DEFAULT 0;
```
- 新列必须指定数据类型
- 支持默认值(DEFAULT)子句,用于填充现有记录
- 现有记录的新列值初始化为默认值或NULL
- 内存重新分配策略:可延迟分配,在第一次访问时按需扩展记录空间
**b) 删除列**
```sql
ALTER TABLE sensor_data DROP COLUMN obsolete_flag;
```
- 立即释放该列占用的存储空间
- 如果该列有索引,自动删除相关索引
- 注意:主键列不能被删除
**c) 重命名列**
```sql
ALTER TABLE sensor_data RENAME COLUMN temp TO temperature;
```
- 仅修改元数据,不移动数据
- 保持现有索引,但更新索引元数据中的列名引用
- 如果该列有约束,约束应继续有效
**d) 重命名表**
```sql
ALTER TABLE sensor_data RENAME TO device_metrics;
```
- 仅修改表名元数据
- 所有索引、约束保持有效
- 已编译的查询计划可能需要失效并重新准备
**3. ALTER TABLE 高级功能(可选,按优先级)**
**e) 修改列类型**(有限支持)
```sql
ALTER TABLE sensor_data MODIFY COLUMN value DOUBLE PRECISION;
```
- 仅支持不改变数据二进制表示的扩展转换(如INT32→INT64,FLOAT→DOUBLE)
- 不支持可能丢失精度的收缩转换(如INT64→INT32)
- 需要重新组织数据,对于大表可能耗时较长
**f) 增加/删除约束**
```sql
-- 增加唯一约束
ALTER TABLE users ADD UNIQUE (username);
-- 删除约束
ALTER TABLE users DROP CONSTRAINT username_unique;
```
- 唯一约束需要创建索引
- NOT NULL约束可动态添加/删除
**4. 编译期DDL与运行时DDL的协同(US-210相关)**
- **编译期声明的表**:
- 仍然支持运行时ALTER,但会生成警告日志
- 修改后的表结构无法在编译期验证
- 建议提供迁移工具,将运行时修改同步回DDL文件
- **运行时创建的表**:
- 完全支持所有DDL操作
- 表元数据存储在专门区域,与编译期表隔离
**5. 事务性与原子性**
- 所有DDL操作必须在事务内执行:
```sql
BEGIN TRANSACTION;
ALTER TABLE sensor_data ADD COLUMN status INTEGER;
UPDATE sensor_data SET status = 1 WHERE value > 100;
COMMIT;
```
- DDL操作失败时,必须完全回滚,不留部分修改
- 支持DDL操作与DML操作在同一个事务中混合执行
**6. 并发控制**
- DDL操作需要获取表级排他锁
- 锁升级机制:当有长时间运行的查询正在访问表时,DDL操作应等待或超时失败
- 提供可配置的锁等待超时(默认:5000ms)
- 支持ONLINE DDL模式(可选):某些操作(如增加NULLABLE列)允许并发读写
**7. 内存管理影响**
- 结构修改对US-104(可配置内存管理)的影响:
- ADD COLUMN:可能触发内存池扩展或记录重新分配
- DROP COLUMN:立即回收内存,但可能有碎片
- 提供内存使用预测:在执行ALTER前估算所需内存
- 修改操作超出内存限制时的行为:
- 如果超过硬上限,操作失败
- 如果超过软上限,触发清理回调
**8. 持久化与恢复**
- 所有DDL操作必须记入WAL(US-107)
- 日志格式需要扩展以支持DDL操作类型
- 崩溃恢复时,重放DDL日志必须保证幂等性
- 检查点(快照)必须包含完整的表结构信息
**9. 性能要求**
- 轻量级操作(重命名表/列):< 10ms
- 中等操作(增加可为NULL的列):< 50ms(10,000条记录的表)
- 重量级操作(修改列类型):需要进度反馈,允许后台执行
- DDL操作期间,对未修改表的查询性能影响< 5%
**10. 资源约束**
- 最大表数量限制(US-101):DROP TABLE后,计数减少,可创建新表
- 单记录最大大小(512字节):ADD COLUMN不能超过此限制
- 每表最大列数(US-214):ALTER不能超过编译时或运行时配置的限制
**11. 错误处理与验证**
- 语法验证:无效DDL语句给出清晰错误信息
- 语义验证:检查约束冲突、类型兼容性、名称重复等
- 资源验证:检查内存、存储空间是否足够
- 依赖验证:检查是否有视图、索引、触发器依赖(未来扩展)
**12. 系统表支持**
- 新增`__system_tables`系统表,记录所有表的结构信息
- 新增`__system_columns`系统表,记录所有列的元数据
- 查询系统表获取表结构信息:
```sql
SELECT * FROM __system_tables WHERE table_name = 'sensor_data';
SELECT * FROM __system_columns WHERE table_name = 'sensor_data';
```
**13. 向后兼容性**
- 现有数据格式兼容:旧版本数据库文件应能加载,忽略未知DDL特性
- API兼容:现有应用程序使用旧API应继续工作
- 提供表结构版本号,支持多版本结构共存(有限场景)
---
**技术约束与限制:**
1. **不支持的操作**(第一期):
- 跨表操作(如合并表、拆分表)
- 修改主键列
- 增加自增列
- 复杂约束(外键、检查约束)
2. **编译期与运行时的权衡**:
- 编译期定义的表结构修改后,编译期类型安全可能失效
- 建议重要表结构仍在编译期定义,运行时DDL主要用于维护和调整
3. **嵌入式环境特殊考虑**:
- 内存受限时,大表结构修改可能失败
- 提供中止机制:长时间运行的ALTER可被用户取消
- 支持仅元数据修改的操作优先实现
4. **与MVCC的交互**(如果实现US-213):
- DDL操作需要维护多版本的表结构信息
- 旧事务可能访问旧版本的表结构
- 表结构版本需要垃圾回收
---
**测试场景:**
1. **功能正确性测试**:
- 创建表→插入数据→修改结构→查询数据,验证结果正确
- 并发测试:一边修改表结构一边查询数据
- 事务回滚测试:ALTER失败后表状态不变
2. **性能与资源测试**:
- 测量不同规模表(100/10K/100K记录)的ALTER操作时间
- 监控DDL操作期间的内存使用峰值
- 压力测试:连续执行多个DDL操作,验证系统稳定性
3. **恢复测试**:
- 执行ALTER后立即模拟崩溃,重启验证表结构正确
- 从旧版本快照恢复,验证向前兼容性
4. **边界条件测试**:
- 尝试修改不存在的表(应报错)
- 尝试添加重复列名(应报错)
- 在内存不足时尝试ADD COLUMN(应优雅失败)
- 删除正在被查询的表(应阻塞或报错)
5. **集成测试**:
- 与编译期DDL(US-210)集成测试
- 与索引功能(US-102, US-212)集成测试
- 与事务功能(US-205)集成测试
---
**依赖与关联:**
1. **强依赖**:
- US-101(内存表存储):基础存储引擎需要支持动态结构
- US-104(内存管理):内存池需要支持动态调整
- US-107(WAL):DDL操作必须持久化
2. **重要关联**:
- US-210(编译期DDL):运行时DDL与编译期DDL的协同
- US-102/US-212(索引):列删除时需要清理相关索引
- US-205(ACID事务):DDL操作需要事务支持
3. **未来扩展**:
- 为US-303(主从复制)提供DDL操作的复制支持
- 为US-404(时序数据)提供专门的ALTER扩展
---
**实施建议分阶段:**
**阶段1(基础DDL)**:
- DROP TABLE(IF EXISTS)
- ADD COLUMN(可为NULL,有默认值)
- RENAME TABLE/COLUMN
- 系统表查询
**阶段2(完整DDL)**:
- DROP COLUMN
- MODIFY COLUMN TYPE(有限支持)
- 约束管理(UNIQUE, NOT NULL)
**阶段3(高级DDL)**:
- ONLINE DDL(部分操作不阻塞读写)
- 并行DDL(大表操作后台执行)
- DDL操作进度查询
---
**风险与缓解:**
| 风险 | 可能性 | 影响 | 缓解措施 |
| ----------------- | ------ | ---- | -------------------------- |
| 数据结构碎片化 | 中 | 中 | 定期整理工具,延迟分配策略 |
| 长时间锁表 | 高 | 高 | ONLINE DDL选项,超时机制 |
| 内存不足 | 中 | 高 | 预检查机制,增量迁移选项 |
| 版本兼容性 | 低 | 高 | 表结构版本号,迁移工具 |
| 编译期/运行时冲突 | 中 | 中 | 明确的使用规范,警告系统 |
---
**成功指标(KPI):**
1. **功能性**:
- 支持核心DDL操作集(ADD/DROP/RENAME)
- 与现有功能的集成无冲突
2. **性能**:
- 元数据操作(重命名)< 10ms
- 结构变更操作平均延迟 < 100ms(万级记录表)
3. **可靠性**:
- DDL操作崩溃恢复成功率 100%
- 并发访问下的数据一致性 100%
4. **资源效率**:
- DDL操作内存开销 < 操作数据的10%
- 无内存泄漏(通过24小时压力测试)
---
#### **US-216:轻量级JSON数据类型与路径查询**
**作为** 工业物联网和嵌入式应用开发者,**我希望** 在内存数据库中支持高效的JSON数据类型,**以便于** 存储和处理设备配置、动态标签、非结构化传感器数据等半结构化信息,同时保持嵌入式环境下的性能和内存效率。
---
**验收条件:**
**1. JSON列定义与存储**
- 支持在CREATE TABLE语句中定义JSON类型列:
```sql
CREATE TABLE device_configs (
id INTEGER PRIMARY KEY,
device_id INTEGER NOT NULL,
config JSON NOT NULL, -- JSON类型列
tags JSON, -- 可为NULL的JSON列
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
```
- **存储格式优化**:
- 默认使用**MessagePack**二进制格式存储,相比文本JSON减少30-50%空间
- 提供可选的**CBOR**(Concise Binary Object Representation)格式
- 内联存储:< 64字节的JSON直接内联在记录中
- 外部存储:> 64字节的JSON存储在专用JSON内存池中
- **内存布局**:
```rust
// 内部表示
enum JsonStorage {
Inline([u8; 64]), // 内联存储
External { // 外部存储
pool_id: u8, // 内存池ID
offset: u32, // 偏移量
length: u32, // 长度
},
Null, // NULL值
}
```
**2. JSON数据操作API**
**a) 插入与更新**:
```sql
-- 插入JSON数据
INSERT INTO device_configs (id, device_id, config, tags, created_at, updated_at)
VALUES (1, 1001,
'{"sampling_rate": 1000, "thresholds": {"temp": 85.0, "vibration": 0.5}}',
'{"location": "cell-1", "criticality": "high"}',
NOW(), NOW());
-- 更新整个JSON列
UPDATE device_configs
SET config = '{"sampling_rate": 2000, "thresholds": {"temp": 90.0}}'
WHERE id = 1;
-- 部分更新(JSON Merge Patch)
UPDATE device_configs
SET config = json_merge_patch(config, '{"thresholds": {"temp": 95.0}}')
WHERE id = 1;
```
**b) 路径查询与提取**:
```sql
-- 提取标量值
SELECT
id,
json_extract(config, '$.sampling_rate') as rate,
json_extract(config, '$.thresholds.temp') as temp_threshold
FROM device_configs
WHERE device_id = 1001;
-- 提取JSON片段
SELECT
json_extract(config, '$.thresholds') as thresholds_json
FROM device_configs;
-- 路径存在性检查
SELECT id
FROM device_configs
WHERE json_has(config, '$.thresholds.temp') = 1;
```
**3. JSON路径表达式支持**
- **完整路径语法**:
```
$ -- 根对象
$.key -- 对象键访问
$[0] -- 数组索引访问
$[*] -- 数组通配符
$.key[*].sub -- 嵌套通配符
$.key[0:5] -- 数组切片
$.key[?(@ > 10)]-- 过滤表达式(可选)
```
- **编译时路径优化**:频繁使用的路径在编译时预编译为访问计划
**4. JSON索引支持**
**a) 虚拟生成列索引**:
```sql
-- 在JSON路径上创建虚拟列并索引
ALTER TABLE device_configs
ADD COLUMN temp_threshold FLOAT
GENERATED ALWAYS AS (json_extract(config, '$.thresholds.temp'));
CREATE INDEX idx_temp_threshold ON device_configs(temp_threshold);
```
**b) JSON路径索引**(有限支持):
```sql
-- 在特定JSON路径上创建索引
CREATE INDEX idx_config_sampling
ON device_configs(json_extract(config, '$.sampling_rate'));
-- 支持多路径复合索引(最多3个路径)
CREATE INDEX idx_config_thresholds
ON device_configs(
json_extract(config, '$.thresholds.temp'),
json_extract(config, '$.thresholds.vibration')
);
```
**5. 与向量数据集成**(US-601增强)
```sql
-- JSON中的向量数组作为向量字段
CREATE TABLE device_features (
id INTEGER PRIMARY KEY,
device_id INTEGER NOT NULL,
features JSON NOT NULL, -- 包含向量数组
vector VECTOR(128) GENERATED ALWAYS AS (
json_extract_vector(features, '$.embedding')
)
);
-- 混合查询:JSON过滤 + 向量搜索
SELECT * FROM device_features
WHERE json_extract(features, '$.device_type') = 'motor'
AND VECTOR_SIMILAR(vector, @query_vector) < 0.2;
```
**6. 内存管理优化**(与US-104集成)
- **专用JSON内存池**:预分配固定大小的JSON存储块(4KB/块)
- **内存碎片控制**:使用slab分配器减少碎片
- **引用计数**:JSON对象可被多个记录共享(只读场景)
- **大小限制**:
- 单JSON文档最大:16KB(嵌入式环境)
- 嵌套深度最大:16层
- 总JSON内存使用可配置上限
**7. 事务与并发**(与US-205集成)
- **MVCC for JSON**:JSON修改创建新版本,旧版本由GC回收
- **部分更新优化**:只修改的路径创建新版本,未修改部分共享
- **锁粒度**:JSON对象级细粒度锁(读不阻塞写不同路径)
**8. 序列化/反序列化优化**
- **零拷贝访问**:json_extract返回原始存储的引用(只读)
- **延迟解析**:只有访问的路径才被解析
- **结构共享**:修改操作尽量复用未修改部分
- **SIMD加速**:使用SIMD指令加速JSON解析(ARM NEON支持)
**9. JSON函数集**
```sql
-- 构造函数
json_object('key1', value1, 'key2', value2)
json_array(value1, value2, value3)
-- 查询函数
json_extract(json_doc, path) → value
json_extract_text(json_doc, path) → TEXT
json_extract_int(json_doc, path) → INTEGER
json_extract_float(json_doc, path) → FLOAT
json_extract_vector(json_doc, path) → VECTOR
-- 存在性检查
json_has(json_doc, path) → BOOLEAN
json_type(json_doc, path) → TEXT -- 'object', 'array', 'number', 'string', 'boolean', 'null'
-- 修改函数
json_set(json_doc, path, value) → JSON
json_insert(json_doc, path, value) → JSON
json_replace(json_doc, path, value) → JSON
json_remove(json_doc, path) → JSON
json_merge_patch(json_doc, patch) → JSON
-- 聚合函数
json_group_object(key, value) → JSON -- 聚合多行为JSON对象
json_group_array(value) → JSON -- 聚合多行为JSON数组
-- 验证函数
json_valid(json_text) → BOOLEAN
json_schema_valid(schema, json_doc) → BOOLEAN -- 可选,JSON Schema验证
```
**10. 嵌入式环境特殊优化**
- **无堆分配模式**:所有JSON操作使用预分配内存池
- **确定性内存使用**:JSON操作最大内存使用可预测
- **快速路径**:常见操作(如读取顶层字段)有专门优化路径
- **ARM Cortex-M优化**:Thumb2指令集优化版本
**11. 与编译期DDL集成**(US-210扩展)
```rust
// Rust过程宏支持JSON列
#[derive(MemdbTable)]
#[memdb_schema(ddl = "
CREATE TABLE device_configs (
id INTEGER PRIMARY KEY,
config JSON NOT NULL,
tags JSON
);
")]
struct DeviceConfigs;
// 自动生成类型安全的JSON访问方法
let config: JsonValue = table.get_json("config");
let sampling_rate: i32 = config.get_i32("sampling_rate").unwrap_or_default();
// 编译时验证JSON Schema(可选)
#[memdb_schema(ddl = "...", json_schema = "config_schema.json")]
struct DeviceConfigs;
```
**12. 性能指标**
- **插入性能**:1KB JSON插入延迟 < 200μs(STM32F4 @ 168MHz)
- **查询性能**:json_extract(顶层字段)延迟 < 50μs
- **路径查询**:嵌套3层路径查询延迟 < 150μs
- **内存效率**:存储开销 < 原始文本JSON的60%
- **更新性能**:部分更新延迟 < 全量更新的30%
**13. 持久化支持**(US-107/201扩展)
- **WAL日志优化**:JSON部分更新只记录差异
- **快照压缩**:JSON数据在快照中使用字典压缩
- **版本回滚**:支持JSON的MVCC版本回滚
**14. 监控与诊断**
```sql
-- JSON列统计信息
SELECT
table_name,
column_name,
json_column_stats(json_column) as stats
FROM __system_json_columns;
-- 示例统计信息
{
"total_documents": 1000,
"total_size_bytes": 1024000,
"avg_size_bytes": 1024,
"avg_depth": 3.2,
"key_distribution": {"sampling_rate": 1000, "thresholds": 1000},
"type_distribution": {"object": 800, "array": 200}
}
```
**技术约束与限制**
1. **一期限制**:
- 不支持JSON全文索引
- 不支持递归路径查询
- JSON Schema验证为可选功能
- 数组操作仅限于简单索引访问
2. **内存约束**:
- 单个JSON文档最大16KB(可配置)
- 最大嵌套深度16层
- 键名最大长度64字节
3. **嵌入式特殊考虑**:
- 无浮点硬件时,JSON浮点数使用定点数模拟
- 支持禁用JSON完整功能,只保留基础路径查询
**测试场景**
1. **功能正确性**:
- JSON往返测试:插入→查询→验证一致性
- 路径查询嵌套测试:10层嵌套路径访问
- 并发修改测试:多线程同时修改同一JSON不同路径
2. **性能基准**:
- 与SQLite JSON1扩展性能对比
- 不同大小JSON文档的CRUD性能
- 内存碎片化测试(24小时连续运行)
3. **边缘案例**:
- 损坏JSON数据处理
- 内存不足时的优雅降级
- 最大限制测试(16KB文档,16层嵌套)
4. **集成测试**:
- 与向量搜索混合查询
- 与时序数据联合查询
- 事务中的JSON操作原子性
**依赖关系**
- **强依赖**:
- US-101(内存存储):基础存储引擎
- US-104(内存管理):JSON专用内存池
- **重要集成**:
- US-210(编译期DDL):JSON类型安全
- US-601(向量数据):JSON向量提取
- US-205(MVCC):JSON并发控制
- **可选增强**:
- US-406(时序查询):JSON路径上的时序聚合
- US-613(分数融合):JSON字段参与分数计算
**实施阶段**
**阶段1(基础JSON)**:
- 二进制JSON存储(MessagePack)
- 基本路径查询(json_extract)
- 内联/外部存储策略
**阶段2(完整功能)**:
- JSON索引支持
- 部分更新(json_set, json_merge_patch)
- 事务支持与MVCC
**阶段3(高级优化)**:
- SIMD加速解析
- 与向量数据深度集成
- JSON Schema验证
**风险与缓解**
| 风险 | 可能性 | 影响 | 缓解措施 |
| ------------ | ------ | ---- | --------------------- |
| 内存碎片 | 中 | 高 | 专用内存池 + 定期整理 |
| 解析性能 | 高 | 中 | 懒解析 + SIMD优化 |
| 嵌套深度爆炸 | 低 | 高 | 深度限制 + 栈保护 |
| 二进制兼容性 | 中 | 中 | 版本化存储格式 |
**成功指标**
1. **功能性**:
- 支持标准JSON路径查询语法
- JSON列与现有类型系统无缝集成
2. **性能**:
- JSON操作额外开销 < 相同数据文本操作的50%
- 路径查询延迟满足嵌入式实时要求
3. **资源效率**:
- 存储空间 < 文本JSON的70%
- 内存使用可预测且有限
4. **开发者体验**:
- API直观易用,与SQL标准兼容
- 错误信息清晰,调试方便
---
**将此用户故事放置在阶段二(核心优化)中,作为US-210(编译期DDL)的扩展,为嵌入式应用提供灵活的半结构化数据处理能力,同时保持嵌入式数据库的确定性和高性能特点。**
#### **US-217:嵌入式优化的复合主键与组合索引**
**作为** 工业物联网和时序数据应用开发者,**我希望** 数据库支持复合主键(多列主键)和组合索引,**以便于** 高效地存储和查询具有多维度标识的数据(如设备ID+指标ID+时间戳),同时保持嵌入式环境下的性能和内存效率。
---
**验收条件:**
**1. 复合主键定义语法**
- 支持在CREATE TABLE中定义复合主键:
```sql
-- 基础语法
CREATE TABLE sensor_readings (
device_id INTEGER NOT NULL,
metric_id INTEGER NOT NULL, -- 温度、压力等指标类型
timestamp TIMESTAMP NOT NULL,
value DOUBLE NOT NULL,
quality TINYINT DEFAULT 100,
PRIMARY KEY (device_id, metric_id, timestamp) -- 复合主键
);
-- 内联语法(与SQLite兼容)
CREATE TABLE sensor_readings (
device_id INTEGER NOT NULL,
metric_id INTEGER NOT NULL,
timestamp TIMESTAMP NOT NULL,
value DOUBLE NOT NULL,
PRIMARY KEY (device_id, metric_id, timestamp)
);
-- 命名约束语法
CREATE TABLE sensor_readings (
device_id INTEGER NOT NULL,
metric_id INTEGER NOT NULL,
timestamp TIMESTAMP NOT NULL,
value DOUBLE NOT NULL,
CONSTRAINT pk_sensor_readings
PRIMARY KEY (device_id, metric_id, timestamp)
);
```
**2. 复合主键存储优化**
- **紧凑的键编码**:复合键编码为紧凑的二进制格式
```rust
// 复合键的内部表示
struct CompositeKey {
// 键组件按定义顺序存储
components: Vec<KeyComponent>,
// 编码后的二进制表示(变长编码)
encoded: Vec<u8>,
// 哈希值用于快速比较
hash: u64,
}
// 键组件的变长编码策略
enum KeyComponent {
Null, // NULL值(主键列不允许,但索引允许)
Int8(i8), // 1字节整数
Int16(i16), // 2字节整数
Int32(i32), // 4字节整数
Int64(i64), // 8字节整数
Float32(f32), // 4字节浮点
Float64(f64), // 8字节浮点
Timestamp(i64), // 时间戳
String(&str), // 字符串(前缀压缩)
Blob(&[u8]), // 二进制数据
}
```
- **键编码规则**:
- 整数类型:使用变长编码(Varint)
- 浮点数:IEEE 754二进制格式
- 字符串:前缀压缩 + 长度前缀
- 时间戳:毫秒级UNIX时间戳
- 最大键长度:256字节(可配置)
- **内存布局优化**:
```rust
// 基于复合键的存储布局
struct CompositeKeyIndex {
// 主键列数
key_columns: u8,
// 每列的类型和偏移量
column_info: Vec<ColumnInfo>,
// 编码后的键值对存储
entries: BTreeMap<Vec<u8>, RecordPointer>,
}
// 支持两种存储布局:
// 1. 平铺布局:所有列连续存储(默认)
// 2. 分离布局:主键列与数据列分离存储(可选)
```
**3. 组合索引支持**
```sql
-- 复合主键自动创建主键索引
-- 主键索引是特殊的组合索引
-- 辅助组合索引
CREATE INDEX idx_device_metric ON sensor_readings(device_id, metric_id);
-- 包含排序方向的组合索引
CREATE INDEX idx_metric_timestamp ON sensor_readings(metric_id, timestamp DESC);
-- 部分索引(可选,过滤部分数据)
CREATE INDEX idx_active_devices ON sensor_readings(device_id, timestamp)
WHERE device_status = 'active';
-- 覆盖索引(包含非键列)
CREATE INDEX idx_query_covering ON sensor_readings(device_id, metric_id, timestamp)
INCLUDE (value, quality);
```
**4. 查询优化与最左前缀原则**
- **最左前缀匹配**:查询条件必须包含复合索引的最左列才能使用索引
```sql
-- 有效使用索引的查询
SELECT * FROM sensor_readings
WHERE device_id = 1001; -- 使用主键索引的最左列
SELECT * FROM sensor_readings
WHERE device_id = 1001 AND metric_id = 2; -- 使用前两列
SELECT * FROM sensor_readings
WHERE device_id = 1001 AND metric_id = 2 AND timestamp > '2024-01-01';
-- 无法使用索引的查询(缺少最左列)
SELECT * FROM sensor_readings WHERE metric_id = 2; -- 无法使用主键索引
-- 部分使用索引的查询
SELECT * FROM sensor_readings
WHERE device_id = 1001 AND timestamp > '2024-01-01'; -- 只使用device_id列
```
- **查询计划优化**:
```sql
-- 显示查询执行计划
EXPLAIN QUERY PLAN
SELECT * FROM sensor_readings
WHERE device_id = 1001 AND metric_id = 2;
-- 预期输出:
-- SEARCH TABLE sensor_readings USING INDEX pk_sensor_readings (device_id=? AND metric_id=?)
```
**5. 范围查询与排序优化**
- **高效的范围扫描**:
```sql
-- 时间范围查询(使用复合主键)
SELECT * FROM sensor_readings
WHERE device_id = 1001
AND metric_id = 2
AND timestamp BETWEEN '2024-01-01 00:00:00' AND '2024-01-01 23:59:59'
ORDER BY timestamp; -- 自动按索引顺序返回,无需额外排序
-- 多设备批量查询
SELECT * FROM sensor_readings
WHERE device_id IN (1001, 1002, 1003)
AND metric_id = 2
AND timestamp > '2024-01-01'
ORDER BY device_id, timestamp;
```
- **排序优化**:
```sql
-- 利用索引避免排序
SELECT device_id, metric_id, AVG(value) as avg_value
FROM sensor_readings
WHERE timestamp BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY device_id, metric_id
ORDER BY device_id, metric_id; -- 与主键顺序一致,无需额外排序
```
**6. 复合主键的CRUD操作**
```sql
-- 插入(必须提供所有主键列)
INSERT INTO sensor_readings (device_id, metric_id, timestamp, value, quality)
VALUES (1001, 2, '2024-01-01 10:00:00', 23.5, 100);
-- 批量插入优化
INSERT INTO sensor_readings (device_id, metric_id, timestamp, value)
VALUES
(1001, 2, '2024-01-01 10:00:00', 23.5),
(1001, 2, '2024-01-01 10:00:01', 23.6),
(1001, 2, '2024-01-01 10:00:02', 23.7);
-- 更新(必须通过完整主键或范围)
UPDATE sensor_readings
SET value = 24.0, quality = 95
WHERE device_id = 1001
AND metric_id = 2
AND timestamp = '2024-01-01 10:00:00';
-- 删除
DELETE FROM sensor_readings
WHERE device_id = 1001
AND metric_id = 2
AND timestamp < '2024-01-01';
```
**7. 与现有索引类型集成**
- **复合哈希索引**:用于等值查询
```rust
struct CompositeHashIndex {
// 多列哈希组合
fn hash_key(&self, columns: &[KeyComponent]) -> u64 {
let mut hasher = MetroHash::new();
for col in columns {
col.hash(&mut hasher);
}
hasher.finish()
}
}
```
- **复合B+树索引**:用于范围查询和排序
- **复合T-Tree索引**:用于内存中频繁更新的场景
**8. 与MVCC集成**(US-213)
- **版本化的复合键**:每个版本包含完整的主键信息
- **并发控制**:复合主键上的行级锁
- **垃圾回收**:旧版本的复合键记录清理
```rust
struct VersionedCompositeKey {
key: CompositeKey,
version: TransactionId,
next_version: Option<Box<VersionedCompositeKey>>, // 版本链
}
```
**9. 嵌入式优化**
- **编译时确定的最大列数**:复合主键最多支持8列(可配置)
- **内存预分配**:键编码缓冲区预分配
- **快速路径**:常见组合(如INT+INT+TIMESTAMP)有专门优化
- **ARM Cortex-M优化**:使用整数指令集加速键比较
```c
// ARM Thumb2优化的键比较
int compare_composite_key_thumb2(const uint8_t* key1, const uint8_t* key2) {
// 内联汇编优化关键路径
asm volatile(
"ldmia %1!, {r2, r3, r4} \n" // 加载key1
"ldmia %2!, {r5, r6, r7} \n" // 加载key2
"cmp r2, r5 \n"
"bne 1f \n"
"cmp r3, r6 \n"
"bne 1f \n"
"cmp r4, r7 \n"
"1: \n"
: "+r"(key1), "+r"(key2)
:
: "r2", "r3", "r4", "r5", "r6", "r7", "cc"
);
}
```
**10. 复合外键支持**(可选扩展)
```sql
-- 复合外键(如果支持外键)
CREATE TABLE device_alerts (
alert_id INTEGER PRIMARY KEY,
device_id INTEGER NOT NULL,
metric_id INTEGER NOT NULL,
alert_time TIMESTAMP NOT NULL,
FOREIGN KEY (device_id, metric_id)
REFERENCES device_metrics(device_id, metric_id)
);
```
**11. 性能指标**
- **插入性能**:复合主键插入 vs 单列主键,性能差异 < 20%
- **查询性能**:
- 等值查询(完整主键):< 100μs
- 范围查询(最左前缀):< 500μs(1000条记录)
- 部分键查询:性能随匹配列数线性变化
- **内存开销**:
- 每个复合键额外开销:4-16字节(取决于列数)
- 索引内存:不超过数据大小的40%
**12. 监控与诊断**
```sql
-- 复合索引使用统计
SELECT
index_name,
key_columns,
equality_lookups,
range_scans,
avg_lookup_time_ms,
index_size_kb
FROM __system_composite_index_stats
WHERE table_name = 'sensor_readings';
-- 索引推荐
SELECT * FROM index_recommendations
WHERE recommendation_type = 'composite_index';
/*
示例输出:
| 表名 | 推荐列 | 预期收益 | 当前查询 |
|------|--------|----------|----------|
| sensor_readings | (device_id, metric_type) | 查询加速5x | SELECT * WHERE device_id=? |
*/
```
**13. 迁移与兼容性**
- **从单列主键迁移**:
```sql
-- 添加复合主键(需要数据迁移)
ALTER TABLE sensor_readings
DROP PRIMARY KEY,
ADD PRIMARY KEY (device_id, metric_id, timestamp);
```
- **向后兼容**:现有单列主键表继续工作
- **升级工具**:提供复合主键迁移工具
**技术约束**
1. **最大限制**:
- 复合主键最大列数:8列(编译时可配置)
- 复合索引最大列数:8列
- 复合键最大总长度:256字节
2. **类型限制**:
- 主键列不允许NULL值
- 支持类型:整数、浮点、字符串、时间戳、BLOB(有限制)
- JSON类型不能作为主键列
3. **嵌入式限制**:
- 内存受限环境下,复合键列数建议≤4
- 字符串主键列在嵌入式环境中建议定长或短字符串
**实施细节**
**键编码方案**
```rust
// 复合键编码示例
fn encode_composite_key(columns: &[KeyComponent]) -> Vec<u8> {
let mut buf = Vec::with_capacity(32);
for (i, col) in columns.iter().enumerate() {
// 列分隔符(类型+长度)
buf.push(col.type_code());
match col {
KeyComponent::Int32(val) => {
buf.extend_from_slice(&val.to_varint_bytes());
}
KeyComponent::String(s) => {
// 字符串:长度前缀 + 内容
let bytes = s.as_bytes();
buf.extend_from_slice(&(bytes.len() as u16).to_le_bytes());
buf.extend_from_slice(bytes);
}
KeyComponent::Timestamp(ts) => {
// 时间戳:毫秒级
buf.extend_from_slice(&ts.to_le_bytes());
}
// 其他类型...
}
}
buf
}
```
**索引结构**
```rust
// 复合B+树索引
struct CompositeBPlusTree {
order: usize, // 树阶数
root: BPlusTreeNode,
// 插入时保持键顺序
fn insert(&mut self, key: CompositeKey, value: RecordPointer) {
// 1. 编码键
let encoded = key.encode();
// 2. 查找插入位置
let (node, position) = self.find_insert_position(&encoded);
// 3. 插入并可能分裂
self.insert_into_node(node, encoded, value, position);
}
}
// 支持部分键查询
fn search_partial(&self, prefix: &[KeyComponent]) -> Vec<RecordPointer> {
// 使用最左前缀匹配
// 1. 编码前缀
// 2. 在B+树中查找第一个匹配前缀的键
// 3. 遍历所有匹配前缀的键
}
```
**测试场景**
1. **功能正确性测试**:
- 插入重复复合主键应失败
- 部分主键查询返回正确结果
- 范围查询边界条件测试
- 并发插入同设备不同时间戳数据
2. **性能基准测试**:
- 复合主键 vs 单列主键插入性能对比
- 不同列数复合键的查询性能
- 范围查询随数据量增长的性能变化
- 内存使用与键列数的关系
3. **压力测试**:
- 高并发插入(1000个设备,每设备10000个点)
- 长时间运行(24小时)的复合主键表
- 内存不足时的优雅降级
4. **恢复测试**:
- 复合主键表的崩溃恢复
- WAL重放复合键操作
- 从备份恢复复合主键表
**依赖关系**
- **强依赖**:
- US-101(内存表存储):基础存储引擎
- US-102(简单索引机制):索引基础
- **重要集成**:
- US-107(WAL):复合主键操作的持久化
- US-205(ACID事务):复合主键的事务保证
- US-404(时序数据):与时间序列复合主键优化
- **协同优化**:
- US-210(编译期DDL):复合主键的类型安全
- US-212(高级索引):复合索引的多种类型支持
---
#### **US-218:嵌入式安全的表删除(DROP TABLE)**
**作为** 嵌入式应用开发者或系统维护者,**我希望** 通过一条确定性的 `DROP TABLE` 语句安全、彻底地删除数据库中的表及其所有数据,**以便于** 在设备生命周期管理、配置重置或存储空间回收等场景中,能够以事务安全的方式清理不再需要的数据结构,同时保证操作的高性能和系统整体的稳定性。
---
**1. 核心设计原则:嵌入式环境下的安全删除**
在资源受限、通常无专业DBA的嵌入式环境中,`DROP TABLE` 必须是 **显式的、受控的、可预测的**。设计围绕以下原则:
* **安全第一**:默认阻止可能造成数据丢失的意外删除,提供确认机制。
* **资源确定**:删除操作的内存与CPU开销有严格上限,行为可预测。
* **深度集成**:与事务、持久化、内存管理无缝协作,保证系统一致性。
* **优雅降级**:在极端资源条件下,操作能安全中止或转入低资源模式。
**2. 详细语法与语义**
**2.1 基础语法与安全守卫**
```sql
-- 基础语法:删除表,释放所有关联资源
DROP TABLE [IF EXISTS] <table_name> [CASCADE | RESTRICT];
-- 示例
DROP TABLE obsolete_logs; -- 直接删除
DROP TABLE IF EXISTS temp_sensor_data; -- 安全删除(表不存在时不报错)
DROP TABLE user_sessions CASCADE; -- 级联删除依赖对象(未来扩展)
```
* **`IF EXISTS` 子句(必须)**:防止因表名拼写错误或已删除而导致的语句执行失败,是嵌入式脚本健壮性的关键。
* **`CASCADE | RESTRICT` 子句(可选,一期占位)**:
* `RESTRICT`(默认):如果存在依赖该表的视图、外键(未来)等,则删除失败。
* `CASCADE`:同时删除所有依赖对象。**一期实现仅标记,详细功能随未来依赖特性一同实现。**
**2.2 扩展语法:可控的延迟删除**
```sql
-- 标记表为“待删除”,在系统低峰期或下一个检查点异步清理数据
DROP TABLE large_telemetry_data DEFERRED;
-- 立即执行一个之前延迟的删除
COMMIT DEFERRED DELETION FOR TABLE large_telemetry_data;
```
* **应用场景**:删除大表时,避免长时间阻塞系统,适合对实时性要求极高的嵌入式控制回路。
**3. 操作语义与资源回收**
**3.1 原子性操作内容**
执行 `DROP TABLE` 时,必须原子性地删除以下所有关联资源:
1. **表数据**:所有行记录。
2. **所有索引**:主键索引、辅助索引(US-102, US-212)。
3. **内存资源**:
* 表结构元数据。
* 数据页和索引页占用的内存。
* 关联的MVCC版本链(US-213)。
* 统计信息。
4. **系统目录**:从 `__system_tables`, `__system_columns` 等系统表中移除条目。
**3.2 内存回收确定性**
* **立即返还内存池**:被释放的内存**必须立即返还**给创建该表时所属的专用内存池(与 **US-104**、**US-xxx (CREATE DATABASE)** 集成),以供同一数据库内的其他表使用。
* **零内存泄漏**:通过编译期RAII(资源获取即初始化)和引用计数,确保无任何内存遗留。
* **碎片控制**:与内存池分配器协同,标记整块内存区域为可重用,而非逐条释放,最大限度减少碎片。
**4. 与核心架构的深度集成**
**4.1 事务性保证(与US-205集成)**
```sql
BEGIN TRANSACTION;
INSERT INTO new_table ...;
DROP TABLE old_table; -- 删除操作是事务的一部分
COMMIT; -- 只有提交后,删除才真正生效,否则完全回滚
```
* **DROP TABLE 必须作为一个事务操作**。在事务回滚时,被删除的表及其数据必须能完全恢复。
* 实现机制:在事务提交前,表元数据被标记为“待删除”,数据实际清理在提交后发生。
**4.2 持久化与恢复(与US-107/201集成)**
* **WAL日志**:`DROP TABLE` 操作必须作为一条强一致性日志记录写入WAL。日志需包含足够信息,以便在恢复时能重新执行或回滚该操作。
* **检查点/快照**:
* 如果快照发生在 `DROP TABLE` 之后,新快照中不应包含该表。
* 恢复时,从快照点之后重放WAL,遇到 `DROP TABLE` 日志应应用删除。
**4.3 并发控制与访问隔离(与US-213集成)**
* **排他锁**:`DROP TABLE` 需要对目标表获取最高级别的排他锁。
* **优雅的访问冲突处理**:
```c
// 伪代码:删除前的状态检查
if (table->active_queries_count > 0 || table->pending_transactions_count > 0) {
// 选项1:等待(可配置超时,默认5秒)
// 选项2:立即返回错误 "ERROR: table 'xxx' is being accessed by other queries"
return ERR_TABLE_BUSY;
}
```
**4.4 与编译期DDL的协同(与US-210集成)**
对于通过编译期DDL定义的表,运行时 `DROP TABLE` 后:
* **类型安全降级**:Rust编译器在编译时生成的、对应于该表的类型和方法仍然存在,但运行时调用将返回明确的“表不存在”错误。
* **建议工作流**:重要表结构的删除,应同步修改DDL文件并重新编译,确保代码与运行时状态一致。
**5. 性能与资源约束**
| 指标 | 目标(嵌入式环境) | 测量条件 |
| :----------------- | :----------------------------------------- | :------------------------------- |
| **删除空表延迟** | < 100 µs | 仅有表结构,无数据 |
| **删除数据表延迟** | < 5 ms + (记录数 * 0.1 µs) | 1万条记录,含索引 |
| **内存回收完整性** | 100% 无泄漏 | 通过Valgrind或自定义内存追踪验证 |
| **阻塞时间** | 获取排他锁的等待时间可配置,默认不超过5秒 | 并发访问场景下 |
| **CPU开销** | 删除操作期间,其他数据库操作延迟增加 < 10% | 在70%负载基准上测试 |
**6. 安全与可恢复性措施**
1. **二次确认(可选API)**:
```c
// 在真正执行DROP前,可通过API进行预检查
RemdbOpPreview preview = remdb_preview_drop_table("critical_data");
if (preview.estimated_released_memory_kb > 1024) {
// 弹出一个需要用户确认的界面
if (!user_confirmed) return;
}
remdb_execute_drop_table(preview);
```
2. **元数据备份(用于紧急恢复)**:在 `__system_deleted_tables` 中保留已删除表的元数据(如表结构、删除时间)一段时间(如24小时),仅用于审计或极端情况下的手动恢复尝试,不保证数据可恢复。
3. **资源防护**:如果系统检测到当前可用内存已极低,可以拒绝或延迟 `DROP TABLE` 操作(因为回收内存的过程本身也需要少量内存开销)。
**7. 验收测试场景**
1. **功能正确性**:
* 创建表并插入数据 → 执行 `DROP TABLE` → 验证表及所有数据消失,后续访问返回明确错误。
* 在事务中执行 `DROP TABLE` 然后 `ROLLBACK` → 验证表和数据完全恢复。
* 并发测试:当有查询正在读取表时,尝试删除应被阻塞或立即失败(根据配置)。
2. **资源与性能**:
* 删除一个包含10万个索引条目的表,测量内存占用的下降是否与理论值吻合。
* 在持续高负载写入时,执行删除操作,监控系统P99延迟是否符合预期。
3. **恢复与持久化**:
* 执行 `DROP TABLE` → 立即模拟断电 → 重启恢复 → 验证表仍处于被删除状态,且未产生任何残留数据文件。
* 从包含 `DROP TABLE` 操作的旧WAL日志进行恢复,验证过程顺利。
4. **边界与错误**:
* 尝试删除不存在的表(带/不带 `IF EXISTS`)。
* 在只读模式或事务中尝试删除。
* 在数据库已关闭或正在关闭时尝试删除。
---
#### **US-219:嵌入式优化的LIKE模式匹配运算符**
**作为** 在嵌入式设备上处理日志、配置项或设备标识符的开发者,**我希望** 数据库提供一个高效、资源确定且功能完整的 `LIKE` 运算符,**以便于** 我能使用标准的SQL通配符语法对字符串字段进行灵活的模式匹配查询,同时确保在资源受限的环境中,此类查询仍能保持可预测的性能和内存占用,满足实时查询的需求。
---
**1. 核心语法与语义扩展**
* **基础通配符支持**:
```sql
-- %: 匹配任意数量(包括零个)的任意字符
SELECT * FROM logs WHERE message LIKE '%error%';
-- _: 匹配单个任意字符
SELECT * FROM devices WHERE serial_number LIKE 'ABC_123';
-- 组合使用
SELECT * FROM files WHERE path LIKE '/var/log/%2024-%.log';
```
* **转义字符支持**:
```sql
-- 使用 ESCAPE 子句定义转义符(默认为‘\’)
SELECT * FROM metadata WHERE key LIKE ‘%\_internal’ ESCAPE ‘\’; -- 匹配以“_internal”结尾
```
* **与现有查询引擎集成**:
```sql
-- 作为US-206条件查询引擎的一部分,支持与其它条件组合
SELECT * FROM sensor_alerts
WHERE device_id = 1001
AND severity > 2
AND description LIKE ‘%temperature%overt%’;
```
**2. 嵌入式环境的关键优化设计**
**2.1 确定性算法与固定内存占用**
* **禁用回溯算法**:明确不采用正则表达式中常见的、可能导致指数最坏情况复杂度的回溯算法。
* **采用Shift-Or (Bitap) 算法或其变种**:
* **优势**:对于模式长度 <= 机器字长(如64位)的情况,可以在 `O(n)` 时间内完成匹配,仅需几个寄存器和位操作,**无需动态内存分配**。
* **实现**:
```c
// 简化示例:用于嵌入式环境的类Shift-Or匹配核心
int embedded_like_match(const char *text, const char *pattern) {
uint64_t mask[256]; // 预计算的字符掩码表(静态或栈上)
uint64_t state = ~(uint64_t)0;
// ... 初始化mask(编译时常量或一次性计算)
for (const char *t = text; *t; t++) {
state = (state << 1) | mask[(uint8_t)*t];
if ((state & (1ULL << (pattern_len-1))) == 0) {
return MATCH_FOUND;
}
}
return NO_MATCH;
}
```
**2.2 与索引和存储引擎的协同**
* **前缀索引加速**:
```sql
-- 如果对 `hostname` 列创建了索引,以下查询可以利用索引进行范围扫描
SELECT * FROM servers WHERE hostname LIKE 'web-svr-%';
-- 优化器应能识别 `'web-svr-%'` 是“前缀匹配”,并将其转化为:
-- `hostname >= 'web-svr-' AND hostname < 'web-svt-'` (‘t’ 是 ‘s’ 的后继字符)
```
* **验收条件**:对于前缀匹配模式,查询性能应与同等选择性的范围查询相当。
* **与列式存储(可选)集成**:如果启用US-404中的列式存储优化,`LIKE` 操作应能直接在压缩后的字符串块上执行,避免完全解压。
**2.3 资源约束与保护**
* **模式长度限制**:单个 `LIKE` 模式的最大长度被限制为 **64字符**(编译时可调)。这既符合嵌入式场景的典型需求,也是保证Shift-Or等算法在单次机器字内运算的关键。
* **匹配堆栈深度限制**:对于复杂的嵌套`%`通配符,内部状态机的深度有上限,防止极端模式导致栈溢出。
* **CPU周期预算**:可配置每次 `LIKE` 匹配操作的最大CPU周期(或指令数),超时则中止并返回错误,防止拒绝服务攻击或错误模式导致的系统停滞。
**3. 性能指标与验收条件**
| 场景 | 数据规模 | 目标延迟 (P99) | 内存分配 |
| :-------------------------- | :----------------------------------- | :------------- | :--------------------- |
| **前缀匹配 (有索引)** | 10万行 | < 100 µs | 零堆分配, < 100字节栈 |
| **中缀匹配 (`%value%`)** | 1万行 | < 2 ms | 零堆分配, < 1KB栈 |
| **复杂模式 (多个`_`和`%`)** | 1000行 | < 5 ms | 零堆分配, < 2KB栈 |
| **全表扫描LIKE** | 与全表扫描时间相当 + (行数 * 0.1 µs) | 零堆分配 | |
**功能正确性验收**:
1. 完成标准通配符 (`%`, `_`) 和转义功能测试。
2. 验证与 `AND`、`OR`、`NOT` 的逻辑组合正确性。
3. 测试在事务内和MVCC快照下的匹配结果一致性。
4. 验证索引加速逻辑对前缀、后缀(如果索引支持反向)模式的有效性。
**4. 与现有架构的集成点**
* **与 US-206 (条件查询引擎) 集成**:`LIKE` 作为新的 `WHERE` 条件谓词被解析、优化和执行。
* **与 US-102 / US-212 (索引) 集成**:查询优化器能识别可索引的 `LIKE` 模式,并生成利用索引的执行计划。
* **与 US-104 (内存管理) 集成**:整个匹配过程在预分配的栈或线程本地缓冲区内完成,杜绝动态内存分配。
* **与 US-110 (零拷贝) 集成**:对于存储在连续内存区的字符串列,`LIKE` 操作直接对原始数据指针进行,无需拷贝。
**5. 进阶考量与未来扩展**
* **字符集支持**:一期仅支持单字节字符集。未来可扩展UTF-8支持,但需明确其性能影响。
* **大小写敏感**:默认区分大小写。可通过 `LIKE` 或专属的 `ILIKE` 运算符提供不敏感选项。
* **SIMD加速**:在支持SIMD的ARM Cortex-M内核上,可使用NEON指令并行进行多个字符的比对。
**总结**
在 `remdb` 中增加 `LIKE` 运算符,绝非简单地移植一个通用库。本需求的核心在于:**在嵌入式资源的硬约束下,通过精心选择的算法(如Shift-Or)、与索引和存储的深度协同、以及严格的内存与CPU管控,交付一个既符合SQL标准、又具备嵌入式系统所必需的确定性和高性能的模式匹配能力。** 这确保了 `remdb` 在处理设备标识、日志过滤等常见边缘场景时,功能完整且表现可靠。建议将其置于 **阶段二(核心优化)** 作为查询引擎的增强功能实现。
---
#### **US-220:声明式数据库创建与生命周期管理**
**作为** 嵌入式系统或边缘计算节点的开发者,**我希望** 通过一个声明式的 `CREATE DATABASE` 语句来初始化、配置并隔离不同的数据存储单元,**以便于** 在同一物理设备或进程中,为不同的应用、租户或数据类型(如设备A的时序数据、设备B的配置库)创建逻辑隔离且资源可控的独立数据库环境,同时保持极低的运行时开销。
---
**1. 核心设计理念:编译时定义,运行时实例化**
在嵌入式环境中,`CREATE DATABASE` **不**应被理解为在运行时动态创建一个全新的、完全自由的数据库。相反,它应是一个 **“实例化”过程**,基于**编译期已预定义和优化的数据库模式(Schema)蓝图**,分配和初始化一组确定性的运行时资源。
```sql
-- 核心语法
CREATE DATABASE [IF NOT EXISTS] <database_name>
USING SCHEMA <schema_identifier> -- 关键:绑定到编译期定义的Schema
[WITH CONFIGURATION (<option>=<value>, ...)];
```
**2. 详细需求与验收条件**
**2.1 数据库定义与模式绑定**
* **模式(Schema)先行**:数据库的结构(表、列、索引、约束)必须在编译期通过 **US-210(编译期DDL)** 定义。`CREATE DATABASE` 实例化一个具体的数据库时,必须引用一个已编译的Schema ID。
```rust
// 编译期:定义数据库模式 (schema.ddl)
// 文件: schemas/production_v1.ddl
CREATE TABLE devices (...);
CREATE TABLE telemetry (...);
// Rust代码中声明该Schema
#[derive(MemdbSchema)]
#[memdb_schema(file = "schemas/production_v1.ddl")]
struct ProductionSchemaV1; // 此结构体即 `schema_identifier`
```
* **运行时实例化**:
```sql
-- 运行时SQL或API调用:基于 `ProductionSchemaV1` 创建两个独立的数据库实例
CREATE DATABASE line_a USING SCHEMA ProductionSchemaV1;
CREATE DATABASE line_b USING SCHEMA ProductionSchemaV1
WITH CONFIGURATION (max_tables=32, memory_limit='64MB');
```
* **结果**:`line_a` 和 `line_b` 是两个完全独立的数据库实例,拥有相同的表结构,但数据、事务、连接彼此隔离。
**2.2 资源隔离与确定性配置**
* **独立的内存池**:每个数据库实例拥有从全局内存中划分出的**独立、预分配的静态内存池**。这确保了:
* **故障隔离**:一个数据库的内存错误不会污染另一个。
* **性能隔离**:一个数据库的繁重操作不会抢占另一个的关键资源。
* **资源可预测**:符合 **US-104(可配置内存管理)** 和 **US-214(确定性容量)** 的要求。
* **配置继承与覆盖**:数据库实例继承Schema编译期的默认配置(如索引类型),但可以在 `WITH CONFIGURATION` 子句中覆盖:
```sql
CREATE DATABASE high_perf USING SCHEMA TelemetrySchema
WITH CONFIGURATION (
wal_mode = 'ASYNC', -- 覆盖持久化策略
default_index_type = 'T-TREE', -- 覆盖默认索引
temp_store = 'MEMORY' -- 临时数据存储位置
);
```
**2.3 数据库上下文与连接管理**
* **轻量级上下文切换**:提供 API 或 SQL 语句(如 `USE DATABASE line_a;`)在同一个进程内切换当前操作的数据库上下文。切换代价应极低(< 1µs),本质上是切换一个指向不同内存池和元数据的指针。
* **跨数据库查询(有限支持)**:在明确授权和连接模式下,支持只读的跨数据库查询,用于系统监控或聚合分析。
```sql
-- 在监控数据库中,聚合查询产线A和B的总数据量
SELECT 'line_a' as source, COUNT(*) FROM line_a.telemetry
UNION ALL
SELECT 'line_b' as source, COUNT(*) FROM line_b.telemetry;
```
**2.4 生命周期与持久化管理**
* **独立的持久化命名空间**:每个数据库的 WAL 日志(**US-107**)和快照文件(**US-201**)以数据库名称作为命名空间前缀,确保物理隔离。
```
/data/remdb/
├── line_a/
│ ├── snapshot.rdb
│ └── wal_0001.bin
└── line_b/
├── snapshot.rdb
└── wal_0001.bin
```
* **数据库级操作**:
```sql
-- 关闭数据库,优雅持久化并释放资源(除预分配内存池)
CLOSE DATABASE line_a;
-- 重新打开数据库,从持久化存储加载
OPEN DATABASE line_a;
-- 删除数据库(危险操作),释放所有资源,包括持久化文件
DROP DATABASE [IF EXISTS] line_a;
```
* **启动时自动恢复**:系统重启时,可根据配置自动恢复所有需要打开的数据库到一致状态。
**2.5 与核心架构的深度集成**
| 集成模块 | 集成方式与收益 |
| :----------------------- | :----------------------------------------------------------- |
| **US-210 编译期DDL** | `CREATE DATABASE` 的核心。Schema在编译时完成语法检查、代码生成和优化,运行时实例化零解析开销。 |
| **US-104 内存管理** | 每个数据库实例是一个独立的“内存租户”,拥有专属的内存池和配额监控。 |
| **US-107/201 WAL与快照** | 持久化以数据库为单位,实现独立的崩溃恢复和备份恢复粒度。 |
| **US-205 MVCC事务** | 事务ID和版本链以数据库为范围,不同数据库的事务完全独立。 |
| **US-208 UDP发布** | 数据发布可配置为按数据库进行,实现更精细的数据流管控。 |
**3. 技术约束与嵌入式优化**
* **最大数据库实例数**:编译期配置,例如 `no_std` 下 ≤ 8,`POSIX` 下 ≤ 64,防止资源耗尽。
* **零动态模式变更**:数据库实例化后,其结构(Schema)**不可更改**。如需变更,需创建基于新Schema的新数据库并迁移数据。
* **启动时间优化**:多个数据库的并行恢复,利用多核(如果可用)加速启动过程。
* **内存开销**:每个数据库实例的元数据内存开销应 < 10KB。
**4. 验收测试场景**
1. **基础功能测试**:
* 基于同一Schema创建两个数据库,分别插入数据,验证数据完全隔离。
* 执行 `USE DATABASE` 切换,验证操作上下文正确变更。
* 关闭并重新打开数据库,验证数据完整恢复。
2. **资源隔离测试**:
* 向数据库A持续写入直至触发其内存上限警告,验证数据库B的操作完全不受影响。
* 模拟数据库A崩溃,验证数据库B依然可正常提供服务。
3. **性能基准测试**:
* 测量创建、切换、关闭数据库等操作的延迟。
* 对比单数据库与多数据库实例运行时,在相同总负载下的性能差异(目标:额外开销 < 5%)。
4. **恢复与持久化测试**:
* 在多个数据库都有活跃事务时模拟系统崩溃,重启后验证每个数据库都能独立恢复到一致状态。
**5. 总结与定位**
此需求不是要创建一个通用、动态的SQL数据库管理系统,而是为 `remdb` 提供一种**符合嵌入式哲学的资源组织范式**。它强化了 `remdb` 的核心优势:
* **确定性**:通过编译期绑定和静态分配,资源用量和性能完全可预测。
* **隔离性**:为复杂的边缘应用(如一台网关服务多个车间)提供故障和安全隔离。
* **效率**:逻辑隔离避免了为每个应用运行独立进程的巨大开销。
**建议将本需求置于“阶段二:核心优化”中,作为 US-210(编译期DDL) 的自然延伸和 US-104(内存管理) 的重要应用场景,与数据库的基础设施能力紧密耦合。**
---
#### **US-221:嵌入式全功能UTF-8编码支持**
**作为** 需要在全球范围内部署的嵌入式设备开发者,**我希望** 数据库的所有文本处理功能(包括存储、索引、比较、LIKE匹配和JSON处理)都能完整、高效地支持UTF-8编码,**以便于** 我的设备能够正确处理多语言用户输入、国际化日志消息和包含表情符号等Unicode字符的数据,同时仍然满足嵌入式环境对性能和资源确定性的严苛要求。
---
**1. 核心设计原则**
**1.1 分层架构与渐进增强**
UTF-8支持将采用分层架构,确保基础功能在**所有配置下都可用**,而高级功能(如规范化、排序规则)可作为可选模块启用。
```rust
// 核心UTF-8处理模块的配置选项
struct Utf8Config {
validation_level: Utf8ValidationLevel, // 严格/宽松/无
normalization: Option<NormalizationForm>, // NFC, NFD等(可选)
case_mapping: bool, // 大小写映射(可选)
grapheme_cluster: bool, // 字素簇边界(高级)
}
```
**1.2 性能与资源的平衡**
| 操作类型 | 纯ASCII优化路径 | 通用UTF-8路径 | 额外开销目标 |
| ------------ | ------------------- | ------------- | ------------ |
| **长度计算** | O(1) 直接使用字节数 | O(n) 遍历计数 | < 30% |
| **比较操作** | `memcmp` | 字符迭代比较 | < 50% |
| **LIKE匹配** | 字节模式匹配 | 字符感知匹配 | < 100% |
| **索引构建** | 直接字节排序 | 按字符排序 | < 20% |
**2. UTF-8核心功能需求**
**2.1 基础存储与验证**
```sql
-- 所有TEXT类型列自动支持UTF-8
CREATE TABLE multilingual_data (
id INTEGER PRIMARY KEY,
log_message TEXT, -- UTF-8文本
user_input VARCHAR(255), -- UTF-8可变长度
emoji_label CHAR(10) -- UTF-8定长(以字符为单位)
);
-- 插入包含各种Unicode字符的数据
INSERT INTO multilingual_data VALUES
(1, '正常ASCII文本', '普通输入'),
(2, '中文测试', '日本語テスト'),
(3, 'Emoji 🚀 和混合文本', '🔥 Hot!'),
(4, 'Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘表情!', '特殊');
```
**验证策略**:
- **严格模式**(默认):拒绝无效UTF-8序列,防止安全漏洞
- **宽松模式**:替换无效序列为U+FFFD(�)
- **无验证模式**:仅用于性能关键场景
**2.2 字符感知的字符串操作**
```sql
-- 字符长度(而非字节长度)
SELECT
message,
LENGTH(message) AS byte_length,
CHAR_LENGTH(message) AS char_length -- 新增:字符数
FROM multilingual_data;
-- 字符位置操作
SELECT
SUBSTRING(message FROM 3 FOR 2) AS chars_3_to_4, -- 字符位置
LEFT(message, 5) AS first_5_chars
FROM multilingual_data;
-- 示例结果:
-- 'Emoji 🚀 和混合文本' | byte_len=23 | char_len=10
-- SUBSTRING: 'ji 🚀' (注意:🚀是单个字符)
```
**2.3 增强的LIKE运算符(扩展US-219)**
```sql
-- UTF-8感知的LIKE匹配(字符为单位)
SELECT * FROM logs WHERE message LIKE '%🚀%'; -- 匹配包含火箭emoji
SELECT * FROM users WHERE name LIKE '_大_'; -- 匹配三字中文名,中间为"大"
SELECT * FROM texts WHERE content LIKE 'Café%'; -- 正确匹配带重音字符
-- 可选的校对规则敏感匹配
SELECT * FROM data WHERE text LIKE 'cafe%' COLLATE utf8mb4_unicode_ci;
```
**算法优化**:
- 实现UTF-8感知的**Shift-Or/Bitap算法变体**
- 为纯ASCII模式保留快速路径
- 支持预编译的匹配状态机,避免每次解析模式
**3. 索引与排序优化**
**3.1 UTF-8感知的B-Tree索引**
```sql
-- 在UTF-8列上创建索引,支持排序和前缀匹配
CREATE INDEX idx_multilingual ON multilingual_data(log_message);
-- 索引将使用字符感知的比较,而非字节比较
-- 'café' 会正确排序在 'caff' 之前,而不是按字节顺序
```
**索引键编码优化**:
```rust
// 索引键的UTF-8友好编码
struct Utf8IndexKey {
// 为常见字符(ASCII、常用CJK)使用优化编码
// 为复杂字符保留可变长度编码
encoded: Vec<u8>,
// 用于快速比较的辅助信息
fast_cmp_prefix: [u8; 8], // 前几个字符的标准化形式
}
```
**3.2 可配置的排序规则(Collation)**
```sql
-- 指定列的排序规则
CREATE TABLE products (
name TEXT COLLATE utf8mb4_unicode_ci, -- 不区分大小写和重音
sku TEXT COLLATE utf8mb4_bin -- 二进制比较(最快)
);
-- 查询时可指定排序规则
SELECT * FROM products
ORDER BY name COLLATE utf8mb4_zh_0900_as_cs; -- 中文拼音排序
```
**支持的排序规则**(按优先级):
1. `utf8mb4_bin`:二进制,最快,一期支持
2. `utf8mb4_unicode_ci`:Unicode大小写不敏感,二期支持
3. 语言特定规则(如中文拼音),三期支持
**4. 高级Unicode功能(可选模块)**
**4.1 Unicode规范化支持**
```sql
-- 确保文本以规范形式存储和比较
SET NORMALIZATION_FORM = 'NFC'; -- 标准推荐形式
-- 规范化敏感的比较
SELECT * FROM users
WHERE NORMALIZE(username) = NORMALIZE('café'); -- 匹配'café'
```
**4.2 字素簇边界处理**
```sql
-- 处理组合字符(如e + ´ = é)
SELECT
text,
GRAPHEME_LENGTH(text) AS visible_chars, -- 视觉字符数
SUBSTRING(text BY GRAPHEME CLUSTERS FROM 1 FOR 3) AS first_3_clusters
FROM complex_texts;
```
**5. 性能优化与资源约束**
**5.1 内存高效的数据结构**
```rust
// 紧凑的UTF-8字符串表示
struct CompactUtf8Str {
// 内联存储短字符串(≤23字节)
inline_data: [u8; 23],
length: u8, // 字符数(非字节数)
flags: u8, // 编码提示:是否纯ASCII、是否需要规范化等
}
// 长字符串使用共享缓冲区
struct LongUtf8Str {
buffer: Arc<[u8]>, // 共享所有权的字节数组
char_count: u32, // 缓存的字符数,避免重复计算
}
```
**5.2 SIMD加速(ARM NEON / x86 AVX2)**
```c
// 使用SIMD快速扫描ASCII段落
int count_utf8_chars_neon(const uint8_t* str, size_t len) {
// 使用NEON指令并行处理16字节,统计非ASCII起始字节
// 对嵌入式设备特别重要
}
```
**5.3 编译时配置选项**
```toml
# Cargo.toml 特性配置
[features]
default = ["utf8-basic"] # 基础UTF-8验证和存储
utf8-full = ["unicode-normalization", "unicode-segmentation"] # 完整支持
utf8-lite = [] # 最小支持,仅验证
no-utf8 = [] # 禁用UTF-8,仅处理ASCII
```
**6. 嵌入式特殊优化**
**6.1 确定性内存使用**
- 每个UTF-8操作的最大栈分配:256字节
- 无堆分配的快速路径(字符串≤64字节时)
- 可配置的最大字符串长度:默认16KB,适应嵌入式限制
**6.2 低功耗模式**
```rust
// 在电池供电设备上,使用简化算法
struct LowPowerUtf8Processor {
use_simple_validation: bool, // 跳过完整验证
cache_normalized_forms: bool, // 缓存规范化结果
max_complexity_level: u8, // 限制复杂字符处理
}
```
**7. 测试与验证**
**7.1 正确性测试矩阵**
| 测试类别 | 示例输入 | 预期行为 |
| ------------------ | ------------------- | ----------------- |
| **基本多语言平面** | "Hello 世界" | 正确存储和检索 |
| **辅助平面** | "𠮷𠮷𠮷" (U+20BB7) | 支持4字节字符 |
| **组合字符** | "café" (e + U+0301) | 规范化处理 |
| **Emoji序列** | "👨👩👧👦" (家庭emoji) | 字素簇处理 |
| **边缘案例** | 无效UTF-8序列 | 根据配置拒绝/替换 |
**7.2 性能基准**
```rust
// 性能测试套件
benchmark_group!(utf8_benches,
bench_ascii_only, // 纯ASCII性能
bench_mixed_text, // 混合文本
bench_cjk_dense, // 密集CJK文本
bench_emoji_heavy // 大量emoji
);
// 目标:UTF-8操作相比ASCII操作的性能下降
// - 存储/检索: < 20%
// - 比较操作: < 50%
// - LIKE匹配: < 100% (最坏情况)
// - 索引构建: < 30%
```
**8. 集成点与依赖**
**8.1 与现有功能集成**
- **LIKE运算符**:扩展为UTF-8感知
- **JSON支持**:JSON字符串值的UTF-8处理
- **索引系统**:UTF-8感知的键比较和排序
- **全文检索**(未来):词素分析考虑Unicode属性
**8.2 系统表扩展**
```sql
-- 新增系统视图,显示UTF-8相关状态
CREATE VIEW remdb_unicode_status AS
SELECT
'utf8_support' AS feature,
normalization_form,
default_collation,
max_char_length
FROM remdb_system_config;
```
**9. 总结**
UTF-8支持是 `remdb` 成为国际化嵌入式数据库的关键特性。通过分层架构、性能优化和资源控制,本设计在提供完整Unicode功能的同时,坚守了嵌入式系统的核心原则:**确定性、高效性和可靠性**。
**将此需求置于阶段二(核心优化),作为字符串处理、LIKE运算符和国际化支持的基础设施,与US-xxx(LIKE运算符)紧密协同实现。**
### **阶段三:高级功能**
**性能优化**
#### **US-301:批处理操作**
作为数据采集应用开发者,我希望批量处理传感器数据以减少事务开销。
**验收条件:**
1. 支持批量插入API,一次插入最多256条记录
2. 批量操作的事务开销分摊到单条<20%
3. 批量操作失败时提供详细错误信息
4. 支持批量更新和删除(可选)
5. 内存使用优化:批量数据连续存储
---
#### **US-302:缓存感知优化**
作为性能敏感应用开发者,我希望数据访问模式优化CPU缓存利用率。
**验收条件:**
1. 热点数据自动聚集存储
2. 顺序扫描时预取下一个缓存行
3. 数据结构按缓存行对齐(64字节)
4. 缓存命中率比未优化版本提高15%以上
5. 提供缓存统计信息
---
#### **US-303:嵌入式高可用主从复制 (remdbHA)**
**作为** 关键任务嵌入式系统(如边缘网关、电信设备、工业控制器)的架构师,**我希望** 数据库提供内置的、低开销的主从复制与自动故障转移功能,**以便于** 在单个节点发生软件或硬件故障时,系统能自动、快速地将服务切换至备用节点,从而保障业务的连续性和数据的高可用性。
**验收条件:**
1. **复制拓扑与数据一致性**
- 支持 **一主一从** 或 **一主多从** 的拓扑结构,所有数据修改仅在主节点进行。
- 提供两种可配置的复制一致性模式:
- **同步模式**:事务必须在主节点提交 *并* 在至少一个从节点持久化后,才向客户端返回成功。此模式提供强一致性(RPO=0),确保无数据丢失。
- **异步模式**:事务在主节点提交后立即向客户端返回成功,随后异步传播至从节点。此模式提供更高吞吐量,但极端情况下可能有少量数据丢失风险。
- 复制内容为物理日志(如US-107的WAL)或逻辑操作日志,确保从节点数据状态最终与主节点一致。
2. **自动故障检测与转移**
- 实现基于**心跳机制**的故障检测。主从节点间定期交换心跳消息,当从节点在配置时间内未收到主节点心跳时,将触发故障判定。
- 支持 **自动故障转移**:当确认主节点失效后,一个指定的从节点(优先副本)将自动提升为新的主节点,并开始接受写请求。
- 提供客户端重定向机制(例如,通过轻量级服务发现或连接代理),使应用能在故障转移后自动或半自动地连接到新的主节点。
3. **节点恢复与数据同步**
- 支持 **故障节点重新加入**:当旧主节点恢复后,能作为新的从节点自动重新加入集群,并从当前主节点同步缺失的数据。
- 提供 **全量同步** 与 **增量同步** 机制。新加入或落后过多的从节点,可先通过全量快照进行基础同步,再通过增量日志追平。
4. **嵌入式资源约束与性能**
- 复制机制的内存开销不得超过数据库总内存占用的 **10%**。
- 在100Mbps以太网上,同步复制的平均事务提交延迟增加不超过 **200微秒**(相对于无复制的主节点本地提交)。
- 故障检测到完成切换的总时间(即服务中断窗口)应小于 **2秒**。
- 心跳与复制数据包需精简,并支持可选的CRC校验(与US-108的UDP CRC校验共用基础组件)。
**测试场景:**
1. **数据一致性测试**:
- 在主节点执行一系列包含随机数据的并发事务,在同步复制模式下,验证所有从节点在事务提交后立即拥有完全一致的数据快照。
- 在异步复制模式下,停止主节点,验证从节点上已复制的数据是主节点的一个一致前缀。
2. **故障转移演练**:
- 在持续写入负载下,**模拟主节点进程崩溃**。验证:1) 从节点能在设定时间内(如1.5秒)检测到故障;2) 优先从节点自动成为新主;3) 客户端应用在重试后能向新主节点写入成功。
- **模拟主节点网络隔离**(脑裂场景)。验证集群能通过预定义的仲裁策略(如仅当从节点间能相互通信时)安全地执行切换,避免出现“双主”导致数据混乱。
3. **恢复与同步测试**:
- 将一台已失效一段时间、数据严重落后的旧主节点重新启动并配置为从节点。验证其能自动请求并从当前主节点同步数据,最终达到数据一致状态。
- 测量在全量同步过程中,对主节点正常服务吞吐量的影响(下降应不超过20%)。
4. **资源与性能基准测试**:
- 监控开启同步复制后,在不同负载下(如每秒1k/10k次事务),主节点的CPU使用率增长情况。
- 在资源受限的嵌入式目标板上,验证复制功能与数据库其他核心功能(如事务处理、UDP发布)能稳定共存,无资源耗尽风险。
---
**监控与维护**
#### **US-304:运行时监控接口**
作为系统集成者,我希望监控数据库运行状态,便于系统调优和问题诊断。
**验收条件:**
1. 提供关键指标:内存使用、操作计数、缓存命中率
2. 监控开销<总CPU时间的2%
3. 支持指标重置和快照
4. 通过串口或日志输出统计信息
5. 支持健康检查API
---
#### **US-305:完整性验证工具**
作为测试工程师,我希望验证数据库内部一致性,确保长期运行可靠性。
**验收条件:**
1. 支持离线完整性检查(数据库不运行时)
2. 检查项:数据-索引一致性、内存泄漏、循环引用
3. 检查时间:1MB数据<200ms
4. 提供修复建议(不自动修复)
5. 检查结果可读性高
---
#### **US-306:Python原生绑定与高级API库**
**作为** 嵌入式系统开发者、数据分析师或机器学习工程师,**我希望** 通过一个高性能、符合Python惯用法的原生库来访问remdb数据库,**以便于** 在开发调试、数据分析和AI应用集成等场景中,能够利用Python生态的强大工具链(如Pandas、NumPy、scikit-learn等)直接操作remdb中的数据,提高开发效率和系统集成能力。
---
**验收条件:**
**1. 安装与部署便捷性**
- 提供通过pip直接安装的Python包:`pip install remdb-python`
- 包体积:核心包<2MB,无运行时动态依赖(如无需额外安装数据库客户端)
- 支持Python 3.8+,兼容主流平台:Windows (x64)、Linux (x64/ARM)、macOS
- 提供预编译二进制轮子(wheel),无需用户本地编译C/C++扩展
**2. 核心API设计**
- 提供直观的面向对象API,支持上下文管理器:
```python
import remdb
# 连接到本地或嵌入式数据库
with remdb.connect("file:///path/to/database.rdb") as db:
# 获取表对象
table = db.get_table("sensor_data")
# 插入数据(支持字典或类型化对象)
table.insert({"id": 1, "value": 23.5, "timestamp": "2024-01-01 10:00:00"})
# 查询数据
record = table.get_by_id(1)
print(record["value"])
```
- API与C/C++核心功能完全映射,至少支持:
- 表管理(创建、删除、列举)
- CRUD操作(insert、update、delete、get_by_id)
- 条件查询(US-206)
- 事务支持(US-103/US-205)
- 批量操作(US-301)
- 订阅发布(US-208的可选Python封装)
**3. 零拷贝与高效数据交换**
- 提供**两种数据访问模式**以满足不同场景:
- **安全拷贝模式**:默认方式,返回Python对象的深拷贝,确保内存安全
- **零拷贝视图模式**(可选):通过`memoryview`或类似机制提供对数据库内存的直接只读访问,显著降低大型数据集传输开销,需在API中明确标注(如`table.get_by_id(1, zero_copy=True)`)
- 与NumPy无缝集成:支持将查询结果**零拷贝转换为NumPy数组**:
```python
# 将整列数据直接转换为NumPy数组(零拷贝或单次拷贝)
values = table.get_column_as_numpy("value", dtype=np.float32)
```
- 支持Pandas DataFrame双向高效转换:
```python
# DataFrame -> 数据库表(批量插入)
df = pd.read_csv("sensor_data.csv")
table.insert_from_dataframe(df, batch_size=1000)
# 数据库表 -> DataFrame
df = table.to_dataframe(columns=["id", "value", "timestamp"])
```
**4. 类型系统映射**
- 完整映射remdb数据类型到Python类型:
- 整数 → `int`
- 浮点数 → `float`
- 定长字符串 → `str`(自动截断/填充)
- 布尔值 → `bool`
- 时间戳 → `datetime.datetime` 或 `int`(纳秒时间戳)
- 向量类型(US-601)→ `numpy.ndarray` 或Python `list`
- 支持空值(NULL)映射为Python的`None`
- 提供类型验证和自动转换,在类型不匹配时给出清晰错误信息
**5. 异步与并发支持**
- 提供异步IO接口(async/await),适用于服务器版remdb:
```python
import asyncio
import remdb
async def main():
async with remdb.AsyncConnection("tcp://localhost:9000") as db:
table = await db.get_table("metrics")
# 异步查询
result = await table.query_async("value > ?", params=[100.0])
```
- 线程安全:连接对象可在多线程环境下安全共享
- 连接池支持(针对服务器版):自动管理多个物理连接
**6. 高级查询与AI集成**
- 支持向量查询(US-601-602)的Python化表达:
```python
# 向量相似度查询
results = table.vector_search(
query_vector=np.array([0.1, 0.2, 0.3]),
vector_column="embedding",
metric="cosine",
limit=10
)
# 混合查询(向量+标量)
results = table.hybrid_search(
vector_query={"column": "embedding", "vector": query_vec, "k": 50},
filter_conditions="category == 'tech' AND price < 100.0"
)
```
- 支持查询构建器模式,避免SQL注入:
```python
query = (table.query()
.filter("temperature > ?", 25.0)
.filter("humidity < ?", 80.0)
.order_by("timestamp", descending=True)
.limit(100))
results = query.execute()
```
**7. 性能要求**
- 单次API调用开销(本地嵌入式模式):
- 简单查询(get_by_id):< 500μs(含Python-C边界开销)
- 批量插入(1000条记录):< 50ms
- 内存效率:
- 零拷贝视图模式下,处理1MB数据额外内存开销< 100KB
- 迭代器支持流式处理大型结果集,避免一次性加载所有数据
- 服务器版网络性能:
- 使用高效二进制协议(如基于MessagePack或自定义)
- 支持连接复用和请求流水线
- 序列化/反序列化开销<数据大小的20%
**8. 错误处理与调试**
- 完整的异常层次结构:
```python
try:
record = table.get_by_id(9999)
except remdb.NotFoundError:
print("记录不存在")
except remdb.TransactionError as e:
print(f"事务失败: {e}")
```
- 详细的错误消息,包含错误码和可能的解决方案
- 支持查询性能分析:
```python
# 获取查询执行计划
plan = table.explain_query("value > ?", params=[100.0])
print(plan.estimated_cost, plan.index_used)
# 性能统计
stats = db.get_performance_stats()
print(stats.query_count, stats.avg_latency_ms)
```
**9. 工具与集成**
- 命令行工具:提供`remdb-cli` Python包,用于交互式查询和数据管理
- Jupyter Notebook支持:提供IPython魔法命令和可视化组件
```python
%load_ext remdb
%remdb_connect localhost:9000
# 直接渲染查询结果为表格
%remdb_query SELECT * FROM sensor_data LIMIT 10
```
- 与流行框架集成示例:
- FastAPI/Django集成示例
- 机器学习 pipeline 集成示例(scikit-learn, PyTorch数据加载器)
- 时序数据处理示例(Pandas, Dask)
**10. 文档与测试**
- 完整的API文档(Sphinx生成),包含详细示例
- 交互式教程(Jupyter notebook格式)
- 测试覆盖率>85%,包括:
- 单元测试(所有公共API)
- 集成测试(与嵌入式remdb和服务器remdb的交互)
- 性能基准测试(定期运行,防止性能回归)
- 跨平台兼容性测试
---
**技术约束:**
1. **二进制兼容性**:
- Python扩展模块使用PyBind11或Cython实现,确保ABI稳定性
- 支持多个Python版本(3.8-3.12)无需重新编译
2. **内存管理**:
- 严格管理Python对象与C++内存间的生命周期
- 零拷贝模式下,确保数据库内存不被提前释放
- 循环引用检测和避免
3. **依赖最小化**:
- 核心包仅依赖标准库和NumPy(可选,但推荐)
- 高级功能(如Pandas集成)作为可选子模块
4. **协议兼容性**:
- 与remdb核心版本保持向后兼容
- 版本号跟随核心数据库主版本
---
**测试场景:**
1. **功能正确性测试**:
- 在嵌入式模式(STM32模拟器)和服务器模式下测试所有API
- 验证类型映射的往返一致性(Python→remdb→Python)
- 测试事务的原子性(批量操作中插入失败触发完全回滚)
2. **性能基准测试**:
- 对比Python接口与C原生API的性能差异(目标:开销<2倍)
- 零拷贝模式vs安全拷贝模式的内存使用对比
- 大数据集(100万条记录)查询的流式处理能力
3. **集成测试**:
- 与Pandas的DataFrame往返转换测试
- NumPy数组零拷贝访问的正确性和性能
- 在完整AI pipeline中的使用示例(数据加载→处理→存储)
4. **长期稳定性测试**:
- 内存泄漏测试(24小时压力测试)
- 并发访问测试(多线程、多进程场景)
- 版本升级兼容性测试
---
**依赖与关联:**
- **强依赖**:
- US-101(核心存储引擎):Python接口的基础
- US-103/US-205(事务支持):ACID操作的必要性
- US-210(编译期DDL):Python中类型安全的基础
- **优化协同**:
- US-110(零拷贝访问):Python零拷贝模式的底层支持
- US-208(UDP发布):可选的Python异步订阅接口
- US-404(时序数据):Python中时序操作的专门优化
- **可选增强**:
- US-601(AI向量):Python中向量查询的自然表达
- US-505(百万QPS):服务器版Python客户端的高性能要求
---
**成功指标(KPI):**
1. **开发者体验**:
- 新用户15分钟内完成第一个Python程序接入
- API直觉性评分>4.5/5(通过用户调研)
2. **性能指标**:
- Python接口额外开销<原生C API的200%
- 零拷贝模式下,10MB数据访问时间<100ms
3. **生态指标**:
- PyPI月下载量>1000(如果开源)
- 第三方库集成数量(1年内>5个)
---
### **阶段四:可选扩展**
**领域特定优化**
#### **US-401:时间序列支持(可选)**
作为IoT开发者,我希望优化时间序列数据的存储和查询。
**验收条件:**
1. 时间戳自动索引,支持时间范围查询
2. 数据自动老化(基于时间或数量)
3. 时间窗口聚合函数(sum/avg/min/max)
4. 压缩存储:时间序列数据压缩率>50%
5. 专门的时间序列查询API
---
#### **US-402:低功耗模式(可选)**
作为电池供电设备开发者,我希望数据库在空闲时降低功耗。
**验收条件:**
1. 可配置的空闲检测时间(默认5s)
2. 低功耗模式电流降低>30%
3. 唤醒延迟<10ms
4. 支持深度睡眠模式
5. 功耗统计功能
---
#### **US-403:混合存储引擎(可选)**
作为大容量应用开发者,我希望将冷数据自动迁移到闪存,以便在有限内存中存储更多数据。
**验收条件:**
1. 冷热识别:基于访问频率和时间的自动识别
2. 迁移策略:可配置的迁移阈值和批次大小
3. 透明访问:冷数据访问自动加载回内存
4. 性能衰减:冷数据访问比热数据慢<10倍
5. 闪存磨损均衡:优化闪存写入模式
---
#### **US-404:时序数据全链路优化存储引擎**
**作为** 处理海量传感器与监控数据的嵌入式系统开发者,**我希望** 数据库提供一个从表定义、事务写入到持久化存储的完整时序数据优化方案,**以便于** 在资源受限的边缘设备上,实现高吞吐、低延迟、高压缩比的时序数据全生命周期管理,确保数据从录入到落盘全程高效、一致且节省空间。
**包含US-405嵌入式优化目标**:针对100MHz单核嵌入式CPU的高性能写入优化
**验收条件:**
1. **专用的时序表DDL扩展**
- 扩展DDL语法,支持 `CREATE TIMESERIES TABLE` 关键字。使用此语法创建的表,将自动获得一个 `NOT NULL` 的 `timestamp` 列作为隐式主键之一。
- 在DDL中支持声明时序专属属性:
- `WITH COMPRESSION = (algorithm='delta-delta', enabled=true)`:指定写入时压缩算法。
- `WITH TTL = '30 days'`:定义数据存活时间,过期数据块可被自动清理。
- 通过过程宏(US-210),这些属性将生成对应的 Rust 结构体与表元数据,供核心引擎调用。
2. **事务化的高性能批量写入接口**
- 提供 `write_timeseries_batch(table: &TimeseriesTable, data_points: &[DataPoint]) -> TransactionResult` 专用API。
- 该批量写入操作**必须**作为一个完整的ACID事务(US-205)来执行,确保一批数据要么全部成功插入并立即可见,要么全部回滚。
- 性能目标:
- 通用嵌入式硬件:单次批量写入1000个数据点延迟 **< 8毫秒**,吞吐量不低于 **12万点/秒**
- 100MHz单核嵌入式CPU:单次批量写入1000个数据点延迟 **< 5毫秒**,吞吐量达到 **> 20万点/秒**(US-405优化目标)
3. **多层压缩存储架构**
- **写入时内存压缩**:数据在内存中按列式组织,并应用指定的压缩算法(如Delta-of-Delta、Gorilla),形成不可变的压缩数据块。对典型规则采样的传感器数据,压缩比 **> 3:1**。
- **持久化存储压缩**:当压缩数据块通过WAL(US-107)持久化或创建快照时,**直接写入压缩后的格式**,避免解压再压缩的开销,使持久化I/O数据量减少 **60%** 以上。
- 提供 `COMPRESSION_SAVING_RATIO` 等元数据查询,供监控存储效率。
4. **资源效率与确定性**
- 整个时序数据通路(接收、压缩、事务管理、持久化)的内存使用必须有静态上限,可通过配置预分配。
- 压缩与持久化操作应在后台线程或异步任务中执行,不得阻塞前端实时数据写入管道。
- 压缩上下文内存占用 **< 每数据列 1KB**(US-405优化目标)
**测试场景:**
1. **全链路功能测试**:
- 使用扩展DDL创建一个带压缩和TTL的时序表,并通过过程宏验证生成的代码正确。
- 连续调用批量写入API插入数据,验证数据被自动添加时间戳、成功压缩,并可通过事务进行原子回滚。
- 触发持久化(检查点或日志),验证磁盘文件大小显著小于原始数据大小,并能在重启后正确恢复解压。
2. **性能与一致性基准测试**:
- **吞吐量与延迟**:在持续写入负载下,测量从调用写入API到数据被提交并完成内存压缩的全流程延迟分布(P99)。
- **压缩比验证**:写入不同类型时序数据(平稳、随机、周期性),计算内存和磁盘的实际压缩比,与目标值(如3:1)进行对比。
- **事务一致性**:在批量写入过程中模拟故障,重启后验证数据库处于一致状态,不会出现“半批次”数据。
3. **资源监控测试**:
- 长时间运行高负载写入,观察内存增长情况,确保无泄漏且符合预分配预期。
- 监控在开启压缩和持久化时,CPU使用率是否保持在可接受范围内(如比未开启时增加不超过15%)。
---
#### **US-405:面向嵌入式设备的高效时序数据写入(已合并至US-404)**
**状态:** 已合并至US-404,作为US-404的嵌入式硬件优化增强子需求
**核心优化内容已整合到US-404的以下部分:**
1. **批量写入性能优化**:针对100MHz单核嵌入式CPU的性能目标(延迟<5毫秒,吞吐量>20万点/秒)
2. **压缩效率优化**:压缩比>3:1的具体要求与压缩上下文内存占用限制
3. **资源效率优化**:预分配内存块避免碎片等内存管理策略
**剩余未整合内容:**
1. **自动时间戳管理**
- 在DDL中通过扩展语法(如 `TIMESTAMP AUTO`)为时序表指定时间戳列。
- 写入时,若该字段值为空,则由数据库引擎自动填充为**高精度单调递增时间戳**(微秒或纳秒级,取决于硬件支持)。
- 支持基于硬件RTC或系统时钟的时间源配置。
**事务标准对齐:**
- US-405原引用的US-031原子事务标准已对齐至US-404使用的US-205 ACID事务标准
- 批量写入操作统一遵循US-205定义的ACID事务要求
**测试场景:**
1. **批量写入性能测试**:模拟持续以每秒10万个数据点的速率写入,持续1分钟,验证吞吐量稳定且内存增长可控,无明显的性能下降。
2. **时间戳正确性测试**:在两个设备间进行高频率写入,验证自动生成的时间戳全局单调递增,且精度符合预期。
3. **压缩效率测试**:写入不同类型的数据(规则变化的整数、随机浮点数),验证压缩后内存占用符合预期比例,并测量压缩/解压操作对CPU使用率的影响(应 **< 5%**)。
4. **恢复与一致性测试**:在批量写入过程中模拟断电,重启后验证已持久化数据(若启用)的完整性和时间戳序列的连续性。
#### **US-406:面向实时分析的时序数据智能查询**
**作为** 需要在边缘端进行实时数据分析的工程师,**我希望** 数据库提供一套高度优化的时序数据查询原语,支持快速的范围过滤、聚合、降采样与智能插值,**以便于** 直接在数据产生的位置进行低延迟的实时统计与概要分析,而无需将原始数据全部传回云端。
**验收条件:**
1. **高效时间范围扫描**
- 为时间戳列自动创建并维护**专用时间索引**(如分层式时间索引或TST树)。
- 性能要求:在1亿个数据点的表中,查询任意1小时时间窗口内的所有数据,延迟 **< 100毫秒**。
- 查询计划能高效地利用时间索引,跳过不相关的数据块。
2. **内置流式聚合函数**
- 提供针对时序的内置聚合函数:`sum`, `avg`, `min`, `max`, `count`, `stddev`,以及针对非规则数据的 `first`, `last`。
- 支持在时间范围查询后进行**分组聚合**,例如“按每5分钟统计平均温度”。
- 聚合计算应充分利用预聚合数据(如有)或向量化执行,避免逐点计算。
3. **自动降采样查询**
- 提供 `SAMPLE BY` 子句,例如 `SELECT avg(value) FROM metrics SAMPLE BY 1h`。
- 引擎能够根据降采样粒度,自动从最合适的数据源获取数据(如从分钟级聚合物化视图中读取,而非扫描秒级原始数据)。
- 降采样查询性能应比扫描原始数据快 **1个数量级** 以上。
4. **智能插值处理**
- 为查询提供 `FILL` 子句,以处理时间序列中的缺失点,支持插值策略:`PREV`(前值)、`LINEAR`(线性)、`NEXT`(后值)、固定值。
- 插值逻辑在查询引擎层高效完成,避免对应用层暴露数据缺失的复杂性。
5. **资源可控的查询执行**
- 所有查询操作(特别是全时间范围扫描)的内存使用应有明确上限,防止因大查询导致内存耗尽。
- 提供查询超时机制,避免复杂查询长时间占用CPU。
**测试场景:**
1. **范围查询基准测试**:构建一个包含多年历史数据的超大型时序表,测试随机时间窗口查询的延迟,验证其不随数据总量线性增长,而是由索引效率决定。
2. **聚合准确性测试**:对同一数据集,分别使用数据库内置聚合和全量扫描后外部计算的结果进行对比,必须完全一致。
3. **降采样性能对比**:对同一查询,分别使用 `SAMPLE BY` 和不使用(在应用层处理)进行对比,验证数据库内置降采样在延迟和CPU使用上的优势。
4. **插值功能测试**:构造有规律缺失的数据序列,使用不同 `FILL` 策略查询,验证返回的结果符合该插值算法的预期,并且处理延迟可接受。
5. **混合负载测试**:在持续高吞吐数据写入的同时,并发执行多个复杂的时序聚合查询,验证查询性能保持稳定,写入性能不受显著影响(下降 **< 10%**)。
---
### **阶段五:服务器版**
**百万QPS**
#### **US-501:无锁高并发架构**
作为高性能应用开发者,我希望数据库核心使用无锁数据结构和细粒度并发控制,以便在32核服务器上实现百万级QPS。
**验收条件:**
1. 核心数据结构(哈希表、B+树)实现无锁版本
2. 支持多核并行查询,查询性能随核心数线性扩展(32核下至少25倍提升)
3. 内存操作使用RCU(Read-Copy-Update)或类似技术,实现零拷贝读取
4. 实现NUMA感知的内存分配和线程绑定
5. 支持线程本地缓存,减少跨核心数据共享
6. 单个查询延迟99分位线<50μs
7. 在32核/256GB内存服务器上,实现>100万QPS(混合读写场景)
**测试场景:**
- 32线程并发测试,验证线性扩展性
- 不同NUMA节点配置下的性能测试
- 长时间压力测试(24小时)验证无锁算法的正确性
- 与主流内存数据库(Redis、Memcached)的性能对比
------
#### **US-502:零拷贝网络栈优化**
作为网络敏感应用开发者,我希望数据库网络层实现零拷贝和批处理,以便最大化网络吞吐量并降低CPU使用率。
**验收条件:**
1. 实现基于io_uring的异步网络I/O(Linux 5.1+)
2. 支持零拷贝数据发送(sendfile、splice等技术)
3. RESP协议解析使用SIMD指令(AVX2/AVX-512)加速
4. 命令批处理:单次系统调用处理多个客户端请求
5. 支持内核旁路(Kernel Bypass)技术选项(如DPDK)
6. 网络吞吐量:单节点>40Gbps,CPU使用率<50%
7. 连接管理支持百万级并发连接
**测试场景:**
- 使用dpdk-testpmd测试网络吞吐量
- 高并发连接测试(100万并发连接)
- 网络延迟测试(P99延迟<100μs)
- 对比不同网络I/O模型性能(epoll vs io_uring)
------
#### **US-503:内存与缓存极致优化**
作为内存敏感应用开发者,我希望数据库内存访问模式极致优化,以便最大化CPU缓存命中率并减少内存带宽消耗。
**验收条件:**
1. 数据结构紧凑设计:记录头部压缩到8字节以内
2. 支持缓存行对齐(64字节)和内存页对齐(4KB)
3. 实现软件预取(prefetch)提示优化
4. 使用透明大页(THP)减少TLB缺失
5. 支持内存访问模式分析工具,指导数据结构布局优化
6. 内存带宽使用:随机读取场景下<80GB/s(DDR4-3200)
7. L1/L2缓存命中率>95%,TLB命中率>99%
**测试场景:**
- 使用Intel VTune或perf分析缓存命中率
- 不同内存对齐方式下的性能对比
- 透明大页开启/关闭的性能影响
- 内存带宽压力测试
------
#### **US-504:高效持久化与日志优化**
作为高吞吐持久化应用开发者,我希望持久化机制对性能影响最小化,以便在高QPS下仍能保证数据安全。
**验收条件:**
1. 实现组提交(Group Commit):批量事务一次性写入日志
2. 支持异步持久化模式:数据先返回客户端,后台持久化
3. 日志写入使用O_DIRECT绕过内核页缓存
4. 支持SSD优化访问模式(对齐4KB,避免写入放大)
5. 持久化延迟:同步模式<100μs,异步模式<10μs
6. 日志压缩使用硬件加速(如Intel QAT)
7. 支持持久化内存(PMEM)作为日志存储
**测试场景:**
- 不同持久化模式下的性能对比
- 断电恢复测试,验证数据一致性
- SSD寿命测试(写入放大系数<1.2)
- PMEM与传统SSD的性能对比
------
#### **US-505:百万QPS性能测试框架**
作为性能工程师,我希望有完善的性能测试框架,以便准确测量和验证百万QPS性能。
**验收条件:**
1. 支持多种负载模式:只读、只写、混合、热点访问、随机访问
2. 可配置的客户端行为:连接数、并发数、请求模式
3. 实时性能监控:QPS、延迟分布、CPU使用、内存带宽
4. 自动化基准测试:一键运行完整性能测试套件
5. 支持分布式压力测试:多台客户端机器同时测试
6. 结果分析与报告生成:自动生成性能报告和对比图表
7. 支持与Redis、KeyDB、Dragonfly等竞品的性能对比
**测试场景:**
- 百万QPS验证测试(32核/256GB内存)
- 线性扩展性测试(1-32核心)
- 长时间稳定性测试(7*24小时)
- 极端场景测试(连接闪断、内存压力等)
---
### **阶段六:AI Native原生**
**核心存储引擎**
#### **US-601:AI原生向量数据模型**
作为AI应用开发者,我希望向量是与INT、STRING同等的基础数据类型,支持直接在CREATE TABLE中定义维度、距离度量及量化算法,以便于构建原生向量数据库应用。
**验收条件:**
1. 能够使用CREATE TABLE语句创建包含向量字段的表,语法为:CREATE TABLE table_name (id INT PRIMARY KEY, vec VECTOR(768) WITH DISTANCE=L2, meta STRING);
2. 向量字段支持基本的CRUD操作
3. 向量索引
-支持精确搜索和近似最近邻搜索。
-支持 L2 距离、内积和余弦相似度计算。
-支持 HNSW/HNSW_SQ/HNSW_BQ 索引,索引列最大维度为 1024 。
-支持 IVF/IVF_PQ 索引,索引列最大维度为 1024 。
4. 向量搜索 SQL 运算符
- 支持向量加、减、乘、比较、聚合等基础运算操作符。
5. 向量混合搜索
- 支持全文索引和向量索引的混合搜索。
- 支持向量数据与标量数据的混合搜索。
**技术约束:**
- 向量维度必须在创建表时指定,不支持动态修改
- 单向量最大维度:4096
- 默认采用 NULL first 比较模式,所以对 NULL 值进行排序时会将其放至最前,建议查询的时候加上 NOT NULL 条件。
**测试场景:**
- 功能测试:执行CREATE TABLE语句创建向量表,验证语法正确性
- 功能测试:对向量字段执行INSERT、SELECT、UPDATE、DELETE操作,验证结果正确性
- 性能测试:插入100万条向量数据,验证插入性能
---
#### **US-602:混合查询支持**
作为AI应用开发者,我希望向量相似度搜索能与标量过滤、范围查询无缝组合,无需应用层拼接,以便实现复杂查询逻辑。
**验收条件:**
1. 支持向量相似度搜索与标量过滤的组合查询,语法为:SELECT * FROM docs WHERE VECTOR_SIMILAR(embedding, $query_vec) AND category = 'tech' LIMIT 10;
2. 支持向量相似度搜索与范围查询的组合,语法为:SELECT * FROM docs WHERE VECTOR_SIMILAR(embedding, $query_vec) AND timestamp > '2023-01-01' LIMIT 10;
3. 混合查询性能损耗<30%(相较于纯向量查询)
**测试场景:**
- 功能测试:执行多种组合查询,验证结果正确性
- 性能测试:比较纯向量查询与混合查询的性能差异,验证性能损耗<30%
---
#### **US-603:工业级单机存储引擎**
作为系统架构师,我希望数据库具备ACID事务支持、预写日志和检查点机制,以保证数据的可靠性和持久性。
**验收条件:**
1. 支持事务语法:BEGIN TRANSACTION; INSERT INTO docs VALUES (...); INSERT INTO docs VALUES (...); COMMIT;
2. 事务中任一操作失败,整个事务回滚,数据保持一致性
3. 系统崩溃后重启,已提交数据不丢失
4. 所有数据修改先写入WAL,再更新内存和主存储
5. 支持至少2种WAL刷盘策略:per write 和 per N seconds
6. 后台自动创建检查点,检查点创建不影响前端查询性能
7. 支持手动触发检查点,语法为:CREATE CHECKPOINT;
**技术约束:**
- 事务嵌套深度:1层
- WAL文件自动轮转和清理
**测试场景:**
- 功能测试:执行包含多个操作的事务,验证原子性
- 可靠性测试:执行事务后kill -9进程,重启后验证数据一致性
- 功能测试:验证自动和手动检查点的创建
- 可靠性测试:创建检查点后kill -9进程,重启后验证恢复正确性
---
#### **US-604:生产级索引管理器**
作为AI应用开发者,我希望数据库支持高性能的向量索引,包括HNSW和IVF_FLAT,以实现快速的相似性搜索。
**验收条件:**
1. 支持至少2种索引类型:HNSW、IVF_FLAT
2. 支持至少3种距离度量:Cosine、L2、IP
3. 支持索引类型相关参数配置,如HNSW的M和ef_construction
4. 支持在线创建索引,语法为:CREATE INDEX idx_embedding ON docs(embedding) USING HNSW WITH (M=16, ef_construction=200);
5. 索引构建过程中,前端读写查询正常执行
6. 支持SHOW INDEX BUILD STATUS命令查看构建进度
7. 索引数据与主数据一同持久化,服务重启后无需重建索引
8. 千万级向量索引加载时间 < 1分钟
9. 亿级向量索引加载时间 < 5分钟
**性能与精度需求:**
- 在千万级向量数据集中,使用HNSW索引(ef_search=128)进行单次查询:P95延迟 < 50ms,召回率(Recall@10)> 98%
- 混合查询性能损耗 < 30%(相较于纯向量查询)
**测试场景:**
- 功能测试:创建不同类型和配置的索引,验证语法正确性和功能正常
- 性能测试:比较不同索引配置的性能差异
- 功能测试:在已有数据上创建索引,验证构建过程不阻塞读写
- 功能测试:使用SHOW INDEX BUILD STATUS命令查看构建进度
- 性能测试:在千万级向量数据集上执行10,000次查询,测量P95延迟
- 精度测试:将近似搜索结果与精确搜索结果对比,计算Recall@10
---
**计算与查询栈**
#### **US-605:工业级AINQL与查询引擎**
作为AI应用开发者,我希望数据库支持完备的客户端协议与SDK,以及SQL-like的查询语法,以便于快速集成和开发应用。
**验收条件:**
1. 同时支持 gRPC(高性能,生产推荐)和 RESTful HTTP(易调试)协议
2. gRPC协议支持所有核心功能,性能测试中吞吐量>10,000 QPS
3. RESTful HTTP协议支持所有核心功能,便于调试和集成
4. 提供功能完整的 Python SDK(支持异步),以及基础的 Go/Java SDK
5. 支持SQL-like查询语法,核心示例:
```sql
SELECT id, doc, cosine_distance(vector, $query_vec) AS score
FROM my_collection
WHERE category = '科技' AND year > 2023
ORDER BY score ASC
LIMIT 10;
```
6. 支持查询参数化,防止注入攻击
7. 支持查询级超时配置,语法为:SELECT * FROM docs WHERE VECTOR_SIMILAR(embedding, $query_vec) TIMEOUT 500ms;
8. 支持最大返回结果数限制
9. 当系统负载超过阈值时,能优雅拒绝新查询,保护系统稳定性
**测试场景:**
- 功能测试:使用不同协议和SDK执行各种查询操作,验证功能完整性
- 性能测试:测量gRPC协议的吞吐量,验证>10,000 QPS
- 集成测试:验证SDK与数据库服务的兼容性
- 功能测试:执行各种AINQL查询,验证语法正确性和结果准确性
- 安全测试:尝试SQL注入攻击,验证系统能有效防御
- 功能测试:执行长查询,验证超时机制生效
- 压力测试:模拟高负载场景,验证查询熔断机制生效
---
#### **US-606:内置模型运行时**
作为AI应用开发者,我希望数据库内置模型推理运行时,支持在查询管道中直接调用嵌入模型,以便实现检索即推理。
**验收条件:**
1. 模型在独立的Model Worker进程中运行,与主数据库进程隔离
2. 支持配置Model Worker的CPU核心数和内存上限
3. Model Worker崩溃或被杀死时,主数据库服务继续正常运行
4. 提供同步调用接口,用于实时查询时的文本向量化
5. 同步接口延迟P99<100ms,支持每秒至少1,000次调用
6. 内置至少1个高质量嵌入模型(如BGE-M3)
7. 支持在查询中直接调用内置模型,语法为:SELECT text_embedding(text, 'BGE-M3') AS embedding FROM docs;
8. 支持从HTTP URL或本地文件路径挂载自定义模型,语法为:CREATE MODEL custom_model USING 'https://example.com/model.onnx' TYPE embedding;
**测试场景:**
- 功能测试:启动数据库服务,验证Model Worker进程独立运行
- 可靠性测试:杀死Model Worker进程,验证主数据库服务继续正常运行
- 资源测试:配置Model Worker资源限制,验证资源使用不超过限制
- 性能测试:测量同步接口的延迟和吞吐量
- 功能测试:使用内置模型生成嵌入向量,验证结果正确性
- 功能测试:从HTTP URL和本地文件加载自定义模型,验证能正常使用
---
**部署与运维**
#### **US-607:单一二进制部署**
作为系统管理员,我希望整个数据库为一个独立的、无外部运行时依赖的可执行文件,以便于部署和运维。
**验收条件:**
1. 数据库为单一可执行文件,无外部依赖(如Java Runtime、Python等)
2. 支持主流操作系统:Linux、Windows、macOS
3. 可直接运行,无需额外安装步骤
**测试场景:**
- 功能测试:在不同操作系统上直接运行二进制文件,验证能正常启动
- 依赖测试:使用ldd(Linux)或otool(macOS)检查二进制文件依赖,验证无外部运行时依赖
---
#### **US-608:基础认证与安全**
作为系统管理员,我希望数据库支持简单的API Key认证和网络安全配置,以保护数据安全。
**验收条件:**
1. 支持API Key认证,配置语法为:SET GLOBAL api_keys=['key1', 'key2'];
2. API Key通过HTTP Header或gRPC Metadata传递
3. 无效API Key请求被拒绝,返回401 Unauthorized
4. 支持API Key的动态更新,无需重启服务
5. 支持配置监听IP,语法为:SET GLOBAL listen_address='0.0.0.0:9000';
6. 支持SSL/TLS加密传输,配置语法为:SET GLOBAL ssl_cert='server.crt'; SET GLOBAL ssl_key='server.key';
7. 支持至少TLS 1.2版本
**测试场景:**
- 功能测试:使用有效和无效API Key发送请求,验证认证机制生效
- 安全测试:尝试各种API Key伪造攻击,验证系统能有效防御
- 功能测试:动态更新API Key,验证无需重启服务即可生效
- 功能测试:配置不同的监听IP,验证服务能正确绑定
- 安全测试:使用OpenSSL验证TLS版本和加密套件
---
**性能优化**
#### **US-609:动态AI数据流优化**
作为实时AI应用开发者,我希望数据库支持流式摄取与实时索引,以及工作负载感知的缓存,以处理动态数据流。
**验收条件:**
1. 支持从Kafka消费数据,配置语法为:CREATE STREAM ingestion FROM KAFKA TOPIC 'docs' WITH CONFIG (bootstrap_servers='kafka:9092');
2. 数据摄入后可见延迟<1s
3. 支持每秒至少10,000条数据的持续摄入
4. 自动识别高频查询,缓存命中率>80%
5. 自动识别热点数据,热点数据访问延迟<1ms
6. 支持动态调整缓存大小和策略
**测试场景:**
- 功能测试:从Kafka发送测试数据,验证数据能被正确摄入和索引
- 性能测试:测量数据摄入到可见的延迟,验证<1s
- 性能测试:测试持续摄入10,000条/秒数据的稳定性
- 性能测试:模拟高频查询,测量缓存命中率,验证>80%
- 性能测试:访问热点数据,测量延迟,验证<1ms
---
#### **US-610:模型计算下推**
作为AI应用开发者,我希望可将轻量级嵌入模型、重排序模型以UDF形式部署在存储层,实现"数据在哪里,计算就在哪里",避免大规模数据移动。
**验收条件:**
1. 支持将模型作为UDF部署,语法为:CREATE MODEL udf_embedding USING 'bge-m3.onnx' AS (text STRING) RETURNS VECTOR(768);
2. 模型UDF支持在查询中调用,语法为:SELECT udf_embedding(text) AS embedding FROM docs;
3. 模型计算下推能减少至少50%的数据传输量
**测试场景:**
- 功能测试:部署模型UDF,在查询中调用,验证结果正确性
- 性能测试:比较模型计算下推前后的数据传输量,验证减少至少50%
---
**数据智能**
#### **US-611:数据谱系与版本化**
作为AI研究者,我希望支持对指定集合创建数据快照,并可通过快照ID进行历史数据查询或恢复,服务于AI实验的可复现性。
**验收条件:**
1. 支持创建集合快照,语法为:CREATE SNAPSHOT docs_snapshot ON docs;
2. 支持通过快照ID查询历史数据,语法为:SELECT * FROM docs@docs_snapshot WHERE id = 1;
3. 支持从快照恢复数据,语法为:RESTORE TABLE docs FROM SNAPSHOT docs_snapshot;
4. 快照创建时间<1分钟(对于100万条数据的集合)
5. 每条数据自动记录谱系信息,包括源文件、提取位置、嵌入模型版本、处理时间
6. 支持通过数据ID查询完整谱系,语法为:SELECT lineage FROM docs_lineage WHERE data_id = 1;
**测试场景:**
- 功能测试:创建快照、查询快照数据、从快照恢复,验证各操作正确性
- 性能测试:测量快照创建时间,验证<1分钟
- 可靠性测试:从快照恢复数据后,验证数据完整性
- 功能测试:插入数据,验证谱系信息自动记录
- 功能测试:查询数据谱系,验证信息完整性
---
#### **US-612:可观测性**
作为系统管理员,我希望数据库提供全面的监控指标和结构化日志,以便于运维和故障排查。
**验收条件:**
1. 通过 /metrics 端点暴露Prometheus格式指标,至少包括:vecdb_query_duration_seconds (分位数)、vecdb_index_cache_hit_rate、vecdb_active_connections、vecdb_wal_size_bytes
2. 所有操作日志以JSON格式输出,包含请求ID、用户、耗时等关键字段
3. 提供 /health(健康检查)、/config(配置查看)、/debug/pprof(性能剖析)等运维端点
4. 日志包含关键查询的召回率估算,格式为JSON
5. Model Worker暴露Prometheus格式的模型推理指标,包括P99延迟、吞吐量和错误率
6. 提供AI专属监控指标:vecdb_index_recall_rate、vecdb_query_cache_hit_rate、vecdb_retrieval_token_cost
**测试场景:**
- 功能测试:访问 /metrics 端点,验证返回有效的Prometheus格式指标
- 监控测试:验证指标能被Prometheus正确采集
- 功能测试:执行操作,验证日志格式和内容符合要求
- 功能测试:访问各个管理端点,验证返回内容符合要求
- 健康检查测试:模拟服务异常,验证/health端点返回非200状态码
- 功能测试:执行查询,验证日志中包含召回率估算信息
- 功能测试:访问Model Worker的metrics端点,验证模型推理指标存在
---
**高级查询功能**
#### **US-613:分数可编程**
作为AI应用开发者,我希望提供SCORE FUSION子句,允许用户自定义函数(如RRF, 加权求和)来融合来自向量、关键词、图关系的多元相关性分数。
**验收条件:**
1. 支持SCORE FUSION子句,语法为:SELECT * FROM docs WHERE SCORE FUSION([VECTOR_SIMILAR(embedding, $query_vec), FULLTEXT_MATCH(content, $query_str)]) USING RRF LIMIT 10;
2. 支持至少2种内置融合算法(RRF, 加权求和)
3. 支持自定义融合函数
**测试场景:**
- 功能测试:使用不同融合算法执行查询,验证结果正确性
- 功能测试:使用自定义融合函数执行查询,验证结果正确性
---
#### **US-614:多模态联合检索**
作为AI应用开发者,我希望支持单一查询语句跨不同模态(文本、图像、音频)的向量空间进行联合检索与结果归并,以便实现多模态AI应用。
**验收条件:**
1. 支持跨模态联合检索,语法为:SELECT * FROM multimodal_docs WHERE CROSS_MODAL_SIMILAR(vector, $query_vec, modalities=['text', 'image']) LIMIT 10;
2. 支持至少3种模态(文本、图像、音频)
3. 支持结果归并与排序
**测试场景:**
- 功能测试:执行跨模态联合检索,验证结果正确性
- 功能测试:验证不同模态的结果能够正确归并排序
---
#### **US-615:会话与序列原生支持**
作为会话AI开发者,我希望提供SESSION或SEQUENCE类型,用于直接存储和管理多轮对话、Agent执行链等具有严格时序关系的数据单元。
**验收条件:**
1. 能够创建包含SESSION类型的表,语法为:CREATE TABLE conversations (session_id SESSION PRIMARY KEY, message STRING, timestamp TIMESTAMP);
2. 支持按会话ID查询完整会话历史,保持时序关系
3. 支持会话数据的原子更新
**测试场景:**
- 功能测试:创建会话表,插入多条会话数据,验证查询结果保持时序
- 并发测试:多个客户端同时更新同一会话,验证数据一致性
---
**高级存储功能**
#### **US-616:分级存储自动化**
作为系统管理员,我希望基于数据访问模式(热度、时效性),自动在内存 -> SSD -> 对象存储间迁移数据,并对查询保持透明,以优化存储成本。
**验收条件:**
1. 支持配置多级存储策略,语法为:ALTER TABLE docs SET STORAGE_POLICY (hot_ttl=2h, warm_ttl=30d);
2. 数据自动根据访问模式在不同存储层级间迁移
3. 分级存储对查询透明,无需修改查询语句
**测试场景:**
- 功能测试:配置分级存储策略,验证数据根据访问模式自动迁移
- 功能测试:查询不同存储层级的数据,验证结果正确性和透明性
- 成本测试:测量分级存储的存储成本节约
---
#### **US-617:图向量融合**
作为图AI应用开发者,我希望支持在图数据库的节点和关系上直接附加向量属性,并能基于向量相似度进行图遍历的路径剪枝或起点选择。
**验收条件:**
1. 能够创建包含向量属性的图节点和关系,语法为:CREATE NODE TYPE user (id INT PRIMARY KEY, profile_vec VECTOR(768));
2. 支持基于向量相似度的图遍历,语法为:TRAVERSE FROM (SELECT * FROM user WHERE VECTOR_SIMILAR(profile_vec, $query_vec) LIMIT 5) MAX_DEPTH 3;
3. 图遍历过程中支持基于向量相似度进行路径剪枝
**测试场景:**
- 功能测试:创建图节点和关系,附加向量属性,执行向量相似度图遍历,验证结果正确性
- 性能测试:在包含100万节点的图上执行向量相似度图遍历,验证性能
---
**性能极致优化**
#### **US-618:无锁高并发架构**
作为高性能AI应用开发者,我希望数据库核心使用无锁数据结构和细粒度并发控制,以便在多核服务器上实现更高的查询性能。
**验收条件:**
1. 核心数据结构(哈希表、B+树)实现无锁版本
2. 支持多核并行查询,查询性能随核心数线性扩展
3. 内存操作使用RCU(Read-Copy-Update)或类似技术,实现零拷贝读取
4. 实现NUMA感知的内存分配和线程绑定
5. 单个查询延迟99分位线<50μs
**测试场景:**
- 多线程并发测试,验证线性扩展性
- 不同NUMA节点配置下的性能测试
- 长时间压力测试(24小时)验证无锁算法的正确性
---
#### **US-619:零拷贝网络栈优化**
作为网络敏感AI应用开发者,我希望数据库网络层实现零拷贝和批处理,以便最大化网络吞吐量并降低CPU使用率。
**验收条件:**
1. 实现基于io_uring的异步网络I/O(Linux 5.1+)
2. 支持零拷贝数据发送(sendfile、splice等技术)
3. 命令批处理:单次系统调用处理多个客户端请求
4. 网络吞吐量:单节点>40Gbps,CPU使用率<50%
**测试场景:**
- 使用dpdk-testpmd测试网络吞吐量
- 高并发连接测试
- 网络延迟测试(P99延迟<100μs)
---
**高级安全与管理**
#### **US-620:完整的RBAC支持**
作为企业级AI应用开发者,我希望数据库支持完整的基于角色的访问控制(RBAC),以便于管理不同用户的权限。
**验收条件:**
1. 支持创建角色,语法为:CREATE ROLE developer;
2. 支持为角色授予权限,语法为:GRANT SELECT, INSERT ON docs TO developer;
3. 支持为用户分配角色,语法为:GRANT ROLE developer TO user1;
4. 支持细粒度的权限控制,包括表级、行级、列级权限
**测试场景:**
- 功能测试:创建角色、授予权限、分配角色,验证权限控制生效
- 安全测试:验证用户只能执行被授予的操作
---
###
#### **US-621:高效内存分配与回收机制**
作为高性能内存数据库,我希望系统具备高效的内存分配器和垃圾回收机制,以支持高并发、低延迟的向量操作。
**验收条件:**
1. 使用线程本地内存池(Thread-local Memory Pool)减少锁竞争
2. 支持大页内存(Huge Pages)以降低TLB Miss
3. 实现内存碎片整理机制,避免长时间运行后性能下降
4. 提供内存使用统计和预警功能,支持设置内存上限
**测试场景:**
- 性能测试:高并发插入/查询场景下内存分配延迟
- 稳定性测试:长时间运行后内存碎片率监控
- 功能测试:内存超限时触发清理或拒绝写入
---
#### **US-622:异步快照与增量日志**
作为内存数据库,我希望支持异步快照和增量WAL,以平衡性能与持久性。
**验收条件:**
1. 支持配置快照间隔(如每10分钟)
2. 增量WAL支持压缩和合并
3. 重启时支持从最新快照 + WAL恢复
4. 支持快照并行写入,不影响前台查询
**测试场景:**
- 性能测试:快照期间查询延迟变化
- 恢复测试:模拟宕机后数据恢复完整性和速度
---
#### **US-623:多副本与自动故障转移**
作为生产级系统,我希望数据库支持多副本同步/异步复制,并具备自动故障转移能力。
**验收条件:**
1. 支持主从复制(同步/异步)
2. 支持自动选主和故障切换
3. 副本延迟可监控,支持读写分离
4. 支持跨机房部署
**测试场景:**
- 容灾测试:模拟主节点宕机,验证自动切换
- 一致性测试:验证同步复制的一致性保证
---
#### **US-624:租户级资源配额**
作为云原生数据库,我希望支持多租户,每个租户有独立的资源配额和隔离。
**验收条件:**
1. 支持创建租户并分配CPU、内存、存储配额
2. 租户间资源隔离,避免互相影响
3. 支持租户级监控和计费
**测试场景:**
- 隔离测试:模拟某租户高负载,验证不影响其他租户
- 配额测试:验证资源超限时的行为(拒绝/限流)
---
#### **US-625:向量查询优化器**
作为AI原生数据库,我希望查询优化器能智能选择向量索引、距离计算方式和执行计划。
**验收条件:**
1. 支持基于代价的查询优化(CBO)
2. 自动选择最优向量索引(HNSW vs IVF)
3. 支持查询重写,如向量过滤条件下推
4. 支持查询计划缓存
**测试场景:**
- 性能测试:对比优化前后查询延迟
- 功能测试:验证查询计划选择的合理性
---
#### **US-626:向量与标量数据压缩**
作为内存数据库,我希望支持高效的数据压缩算法,以降低内存占用。
**验收条件:**
1. 支持向量量化压缩(如PQ、SQ)
2. 支持标量数据压缩(如ZSTD、LZ4)
3. 支持压缩级别可配置(速度 vs 压缩比)
4. 查询时支持透明解压
**测试场景:**
- 压缩测试:测量压缩比和解压性能
- 查询测试:验证压缩后查询性能无明显下降
---
#### **US-627:实时性能诊断面板**
作为运维人员,我希望有一个可视化的性能面板,实时展示查询延迟、内存使用、索引命中率等。
**验收条件:**
1. 提供Web控制台或Grafana Dashboard
2. 支持实时查询追踪与慢查询分析
3. 支持内存泄漏检测与报告
4. 支持性能瓶颈定位(如锁竞争、IO等待)
**测试场景:**
- 功能测试:验证控制台各项功能可用
- 诊断测试:模拟性能问题,验证诊断工具能准确识别
---
#### **US-628:在线数据迁移工具**
作为系统管理员,我希望支持在线数据迁移和备份,不影响服务可用性。
**验收条件:**
1. 支持从其他向量数据库(如Milvus、Pinecone)迁移数据
2. 支持全量/增量备份
3. 备份支持加密和压缩
4. 支持备份到对象存储(如S3、OSS)
**测试场景:**
- 迁移测试:从外部系统迁移数据并验证一致性
- 备份恢复测试:验证备份完整性和恢复时间
---
#### **US-629:向量查询模拟器**
作为开发者,我希望有一个查询模拟器,可以模拟不同查询负载,测试系统性能。
**验收条件:**
1. 支持生成模拟向量数据和查询
2. 支持回放真实查询日志
3. 提供性能报告和瓶颈分析
**测试场景:**
- 负载测试:使用模拟器生成高负载,验证系统稳定性
- 回归测试:版本升级前后性能对比
---
#### **US-630:数据操作审计日志**
作为企业级系统,我希望所有数据操作都有审计日志,满足合规要求。
**验收条件:**
1. 记录所有数据修改、查询、用户登录等操作
2. 审计日志支持加密存储和防篡改
3. 支持审计日志导出和分析
4. 支持合规报表生成
**测试场景:**
- 审计测试:执行各类操作,验证审计日志完整
- 安全测试:尝试篡改审计日志,验证防篡改机制
---
## 基于STM32F4的高频数据采集程序示例
### **US-701:可靠的高频传感器数据采集与缓存**
**作为** 嵌入式数据采集系统开发者,**我希望** MCU能够利用DMA和双缓冲技术,可靠、不间断地采集多路高频传感器数据(例如≥1KS/s),并缓存在应用层队列中,**以便于** 为上层处理任务提供稳定、连续的数据流,确保在100%的CPU负荷下也不丢失任何采样点。
**验收条件:**
1. 使用ADC DMA配合定时器触发,实现不低于 **1KS/s/通道** 的采样率,且实际采样周期抖动小于 **1%**。
2. 实现**双缓冲DMA传输**,在半满/全满中断中,将数据快速搬移至应用层的无锁环形缓冲区,单次中断服务程序(ISR)执行时间小于 **10微秒**。
3. 应用层环形缓冲区容量至少能容纳 **100ms** 的原始采样数据,防止任务调度延迟导致数据溢出。
4. 提供缓冲区水位监控接口,当占用率超过 **75%** 时产生警告,超过 **90%** 时触发错误处理流程。
### **US-702:传感器数据的原子化事务存储**
**作为** 数据处理任务,**我希望** 能够将缓存的原始采样数据块,经过校准和格式化后,以原子事务的方式批量、高效地写入时序数据库,**以便于** 确保每批采集数据的完整性和一致性,并为后续查询提供高性能的访问接口。
**验收条件:**
1. 提供 `sensor_data_batch_insert(sensor_id, &[CalibratedData])` API,将至少 **256个** 数据点作为一批次进行写入。
2. 该API调用必须作为一个**ACID事务(US-205)** 执行,确保整批数据要么全部入库成功,要么全部回滚。
3. 从环形缓冲区读取一批数据,完成校准转换,到成功提交至 `remdb` 的总延迟,99分位线(P99)小于 **20毫秒**。
4. 写入过程应触发数据库的**实时压缩(US-405)**,对规整的传感器数据(如温度、电压)压缩比不低于 **3:1**。
### **US-703:采集数据的实时聚合与发布**
**作为** 监控客户端或边缘计算模块,**我希望** 能够对刚入库的传感器数据进行低延迟的聚合查询(如每秒平均值),并将结果实时发布给网络上的订阅者,**以便于** 实现系统状态的实时监控和快速闭环控制。
**验收条件:**
1. 提供 `query_realtime_aggregate(sensor_id, agg_func, time_window)` API,查询最近时间窗口(如1秒)内的聚合值,其端到端延迟(从查询调用到返回结果)小于 **50毫秒**。
2. 支持将指定的聚合查询结果,通过 **基于UDP的高可靠数据订阅与发布(US-208)** 自动、周期性地向预订阅的客户端组播。
3. 聚合发布任务与数据采集、存储任务的优先级需合理调度,确保发布任务不会阻塞数据采集的实时性。
4. 在网络带宽受限时,UDP发布机制应能保证 **心跳信号** 的优先传输,维持连接状态感知。
---
## 🎯 关键技术决策调整
### **1. 存储模型:混合模式**
- **内存表**:核心热数据,固定结构,高效访问
- **对象缓存**:可选扩展,支持动态数据
- **权衡**:80%场景用内存表,20%复杂场景用对象缓存
### **2. 持久化策略:检查点为主**
- **主要**:定期全量/增量快照
- **辅助**:可选操作日志(针对关键操作)
- **恢复**:加载最新快照 + 重放关键日志
### **3. 并发模型:读写锁 + 乐观锁**
- **默认**:读写锁,简单可靠
- **可选**:乐观锁(版本号),高并发读场景
- **放弃**:完整MVCC,复杂度太高
### **4. 配置策略:编译时为主,运行时为辅**
- **核心参数**:表结构、内存大小等在编译时确定
- **运行参数**:快照间隔、缓存大小等可运行时调整
- **配置验证**:编译时检查配置合法性
---
## ⚠️ 风险与缓解措施
| 风险 | 可能性 | 影响 | 缓解措施 |
| -------------- | ------ | ---- | --------------------- |
| 内存碎片问题 | 中 | 高 | 使用内存池+定期整理 |
| 持久化性能问题 | 高 | 中 | 增量快照+压缩 |
| 并发死锁 | 低 | 高 | 超时检测+自动回滚 |
| 跨平台兼容性 | 中 | 中 | 抽象层测试+CI/CD |
| 长期运行稳定性 | 中 | 高 | 内存泄漏检测+老化测试 |
---
## 🧪 测试策略调整
### **单元测试**
- 代码覆盖率>85%
- 每个模块独立的测试套件
- 内存泄漏检测集成到测试中
### **集成测试**
- 端到端功能测试
- 跨平台兼容性测试
- API稳定性测试
### **性能测试(Phase里程碑)**
- 基准测试:操作延迟、吞吐量、内存使用
- 对比测试:与SQLite内存模式对比
- 长期运行:72小时压力测试
### **真实场景测试**
- 嵌入式开发板实际部署
- 模拟传感器数据采集场景
- 功耗测量(电池供电场景)
---
## 📊 成功指标(KPI)
### **技术指标**
1. **性能**:点查询延迟<100μs(STM32F4)
2. **内存**:静态内存占用<50KB,每记录开销<额外8字节
3. **可靠性**:崩溃恢复成功率>99.9%
4. **可移植性**:支持至少3种架构+2种RTOS
### **项目指标**
1. **进度**:每Sprint完成计划用户故事的80%以上
2. **质量**:每千行代码bug数<5个
3. **文档**:API文档100%覆盖,示例代码充足
### **业务指标**
1. **易用性**:新用户2小时内完成第一个应用集成
2. **维护性**:平均问题修复时间<2天
3. **社区**:GitHub star>100(如果开源)
---