数据库选型分析.md 6.6 KB

数据库选型分析:RocksDB vs SQLite

文档导航

当前情况

当前使用 RocksDB

  • 存储方式:Key-Value 存储
  • 查询方式:通过 key(deviceId_timestamp)或 key range 查询
  • 数据格式:JSON 序列化存储

未来需求

  • 创建时间、更新时间、创建者、数据等级等多个字段
  • 需要按这些字段进行查询、过滤、排序
  • 数据协议转化和管理

RocksDB 适用性分析

✅ 优点

  1. 高性能写入:写密集型场景性能优秀
  2. 低延迟:适合实时数据写入
  3. 内存占用可控:缓存和压缩机制完善

❌ 缺点(针对您的需求)

  1. 不支持字段级查询

    • 无法直接查询:WHERE creator='张三' AND level > 5
    • 需要全表扫描 + 内存过滤,效率低
  2. 查询能力受限

    • 无法使用 SQL 进行复杂查询
    • 无法使用索引优化查询性能
    • 无法进行聚合统计(COUNT、SUM、GROUP BY)
  3. 数据扩展性差

    • 新增字段需要修改序列化逻辑
    • 难以进行数据迁移和版本管理
    • 不支持数据库级别的字段约束
  4. 维护复杂

    • 需要手动实现索引逻辑(通过额外 key)
    • 查询逻辑复杂(需要自己实现过滤、排序)

推荐方案:SQLite

✅ 为什么选择 SQLite?

  1. 完整的 SQL 支持

    -- 可以直接查询
    SELECT * FROM bus_messages 
    WHERE creator = '张三' 
     AND data_level > 5 
     AND create_time > '2024-01-01'
    ORDER BY create_time DESC;
    
  2. 字段扩展容易

    • 使用 ALTER TABLE 轻松添加字段
    • 支持字段类型约束和默认值
    • 支持外键和索引
  3. 适合中小规模数据

    • 单文件数据库,部署简单
    • 性能优秀(读性能接近 RocksDB)
    • 支持事务和并发
  4. Qt 原生支持

    • Qt 内置 QSqlDatabase,无需额外依赖
    • 与 Qt 集成良好
  5. 数据管理方便

    • 可以用 SQLite 管理工具查看数据
    • 支持数据导入导出
    • 支持备份和恢复

⚠️ 注意事项

  • 写入性能:比 RocksDB 稍慢(但通常足够)
  • 数据规模:适合单机中小规模数据(GB 级别)
  • 并发写:SQLite 3.7+ 支持 WAL 模式,并发性能良好

数据模型设计建议

原始数据表(raw_data)

CREATE TABLE raw_data (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    device_id INTEGER NOT NULL,
    data BLOB NOT NULL,
    create_time INTEGER NOT NULL,        -- 创建时间(时间戳)
    update_time INTEGER,                 -- 更新时间(时间戳)
    creator TEXT,                        -- 创建者
    data_level INTEGER DEFAULT 0,        -- 数据等级
    protocol_type TEXT,                  -- 协议类型
    is_valid BOOLEAN DEFAULT 1,          -- 是否有效
    metadata TEXT,                        -- 元数据(JSON格式)
    FOREIGN KEY (device_id) REFERENCES devices(id)
);

CREATE INDEX idx_raw_data_device_time ON raw_data(device_id, create_time);
CREATE INDEX idx_raw_data_creator ON raw_data(creator);
CREATE INDEX idx_raw_data_level ON raw_data(data_level);

总线消息表(bus_messages)

CREATE TABLE bus_messages (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    message_id TEXT UNIQUE NOT NULL,     -- 消息ID
    source TEXT NOT NULL,
    destination TEXT NOT NULL,
    payload TEXT NOT NULL,                -- JSON格式
    create_time INTEGER NOT NULL,
    update_time INTEGER,
    creator TEXT,
    data_level INTEGER DEFAULT 0,
    protocol_type TEXT,
    is_valid BOOLEAN DEFAULT 1,
    metadata TEXT
);

CREATE INDEX idx_bus_msg_source_dest ON bus_messages(source, destination);
CREATE INDEX idx_bus_msg_time ON bus_messages(create_time);
CREATE INDEX idx_bus_msg_creator ON bus_messages(creator);
CREATE INDEX idx_bus_msg_level ON bus_messages(data_level);

设备表(devices)

CREATE TABLE devices (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    portname TEXT UNIQUE,
    name TEXT,
    type TEXT,
    address INTEGER,
    protocol TEXT,
    protocol_detail TEXT,
    properties TEXT,                     -- JSON格式
    create_time INTEGER,
    update_time INTEGER,
    creator TEXT
);

性能对比

特性 RocksDB SQLite
写入性能 ⭐⭐⭐⭐⭐ 极高 ⭐⭐⭐⭐ 高
读取性能 ⭐⭐⭐⭐⭐ 极高 ⭐⭐⭐⭐ 高
查询灵活性 ⭐⭐ 低(只能按key) ⭐⭐⭐⭐⭐ 极高(SQL)
字段扩展 ⭐⭐ 困难 ⭐⭐⭐⭐⭐ 容易
数据管理 ⭐⭐ 困难 ⭐⭐⭐⭐⭐ 容易
部署复杂度 ⭐⭐⭐ 中等 ⭐⭐⭐⭐⭐ 简单
适合场景 高性能写入、简单查询 复杂查询、数据管理

迁移建议

方案1:直接迁移到 SQLite(推荐)

  • 优点:架构清晰,易于维护
  • 适用:数据量不是特别大(< 100GB),查询需求复杂

方案2:混合方案

  • RocksDB:用于高频实时写入
  • SQLite:用于历史数据查询和分析
  • 定时同步:定期将 RocksDB 数据导入 SQLite
  • 优点:兼顾性能和查询能力
  • 缺点:架构复杂,需要维护两套存储

最终建议

场景1:中小规模数据(推荐 SQLite)

对于数据量中等(< 100GB)的场景,强烈建议使用 SQLite:

  1. 查询能力:SQL 支持复杂查询和索引
  2. 字段扩展:ALTER TABLE 轻松添加字段
  3. 数据管理:易于管理和维护
  4. Qt 集成:原生支持,无需额外依赖
  5. 迁移成本:可以设计兼容接口,逐步迁移

性能影响:对于大多数应用场景,SQLite 的性能足够,且带来的查询灵活性远大于性能损失。

场景2:大数据量时间序列(推荐混合架构)

对于大数据量、高频写入的场景(TB级别、持续采集),建议使用 RocksDB + SQLite 混合架构:

  1. RocksDB:保持高频写入性能,存储实际数据
  2. SQLite:作为索引层,支持复杂查询和字段扩展
  3. 最佳平衡:兼顾写入性能和查询灵活性

详见:大数据量存储方案.md混合架构实现示例.md