第4章 本地数据引擎选型:SQLite、IndexedDB、Dexie、WatermelonDB 的架构权衡与选型决策

4.1 架构边界与上下文

本地数据引擎位于离线优先架构的持久化存储层,上接数据访问层(Repository/DAO),下接文件系统或浏览器内置存储。它在离线期间承载所有结构化数据的写入、查询、索引、事务管理,并在恢复在线后充当同步引擎的数据基座。本章比较的四款引擎涵盖了移动原生(SQLite)、浏览器原生(IndexedDB)以及基于其上封装的现代化库(Dexie.js、WatermelonDB)。

选型边界明确为:浏览器端离线应用(PWA) 与 移动端混合/原生应用 两种场景。不考虑后端持久化。

架构提示: 选型初期即应将引擎视为“可替换组件”,通过依赖倒置原则抽象出统一存储接口,降低后续迁移成本。

4.2 系统分层与模块职责

在典型离线优先架构中,本地数据引擎参与以下分层:

  • 网络同步层: 管理远程 API 推拉,将增量变更写入本地引擎。
  • 数据访问层(Repository/DAO): 封装 CRUD 逻辑,对外提供事务性接口,内部调用引擎 API。
  • 本地数据引擎: 负责物理存储、索引、查询优化、事务与并发控制。
  • 持久化介质: 文件系统(SQLite)、浏览器 IndexedDB 存储。
离线优先架构 — 本地数据引擎在分层中的位置 网络同步层 数据访问层 (Repository/DAO) 本地数据引擎 SQLite IndexedDB Dexie.js WatermelonDB 持久化介质(文件系统 / 浏览器存储) 数据流方向:网络 → 数据访问层 → 引擎 → 持久化介质;查询与变更均经统一接口,引擎内支持事务与索引。

4.3 选型权衡:对比矩阵

维度 SQLite IndexedDB Dexie.js WatermelonDB
运行环境 原生(Android/iOS/桌面) 浏览器(所有现代浏览器) 浏览器(封装 IndexedDB) 原生 + 浏览器(React Native / Web)
事务支持 完整 ACID 有限(单连接序列) 支持(自动事务管理) 内置事务 + 同步标记
查询能力 SQL(JOIN、子查询) 游标 + 索引 链式查询(类似 LINQ) 懒加载 + 关联查询
索引与排序 多字段复合索引 多字段索引(需手动) 自动索引声明 自动索引 + observable
离线同步集成 需自建同步逻辑 需自建 可通过插件扩展 内置同步协议(pull/push)
包体积与加载 ~500KB(sqlite3.c) 浏览器原生,无额外体积 ~45KB(gzip) ~100KB(gzip,含 lodash)
性能(10万行) 批量插入 ~50ms 批量插入 ~200ms 优化后 ~120ms 惰性写入 + 延迟渲染,首屏快
注意: IndexedDB 在 iOS 上的私有模式(Safari 无痕浏览)会耗尽存储空间,且清除数据时难以保留;此场景下应回退至内存存储或提前检测异常。

4.4 数据流与信任链路

本地数据引擎不仅负责持久化,还承担离线信任锚点的角色。每次从网络同步的数据须经过:

  1. 验证阶段: 检查记录 schema 版本、冲突向量(如 Lamport 时间戳)
  2. 写入阶段: 使用引擎事务保证原子写入
  3. 索引刷新: 确保查询可立即命中
  4. 通知层: 触发 UI 更新(如 WatermelonDB 的 observable)

信任链路要求引擎不得丢失已提交事务,且能检测存储介质异常(如 SQLite 的 fsync 失败、IndexedDB 的 quota 超限)。

4.5 风险点与避坑指南

  • SQLite 的多写并发: 在移动端 WAL 模式下可支持读写并发,但写写仍排他;需使用连接池或序列化写入。
  • IndexedDB 的异步陷阱: 所有操作异步,不当的 Promise 链容易导致事务提前关闭。
  • Dexie.js 的版本迁移: Schema 变更时需显式升级版本号,否则数据丢失。
  • WatermelonDB 的惰性加载: 大量关联查询可能触发 N+1 问题,需使用 prefetch 或批量加载。
  • 跨平台一致性: 如果同时使用 Web + Native 混合,选型应优先考虑 cortex(如 WatermelonDB)封装统一的存储接口。

4.6 落地步骤

  1. 根据运行环境锁定候选引擎(浏览器 → IndexedDB/Dexie/WatermelonDB;原生 → SQLite/WatermelonDB)
  2. 制作 POC,对核心场景(离线写入 1000 条 + 复合查询 + 同步冲突)进行压测
  3. 评估学习曲线与调试工具链(如 SQLite 可使用 DB Browser,IndexedDB 可使用 Chrome DevTools)
  4. 设计存储抽象层,将引擎依赖收口到单一 Repository 实现
  5. 实现启动时的 schema 迁移脚本与降级路径
  6. 编写集成测试覆盖:异常写入、同步恢复、存储空间不足

4.7 验收标准

验收项 通过标准
离线写入正确性 模拟离线写入 5000 条数据,恢复在线后无丢失、无重复
查询响应时间 10 万行数据下,复合条件查询 ≤ 200ms
事务隔离性 并发写事务不产生脏读取或部分更新
存储限制处理 达到配额前触发预先警告,且写操作优雅失败
版本迁移 从 v1 迁移到 v3 schema,历史数据完整保留
选型决策摘要:
  • 纯浏览器端、快速迭代: Dexie.js(兼顾易用性与性能)
  • 移动原生重度离线、复杂查询: SQLite(配合 Room 或 DataStore)
  • 跨平台(React Native + Web)、同步集成: WatermelonDB(内置 observable + 同步协议)
  • 轻量 POC、无需额外库: IndexedDB(但小心 iOS 私有模式)