Skip to content

ADR-0006:原型期用 SQLite 实现双库逻辑隔离,落地期换 PostgreSQL ​

  • 状态:已采纳
  • 日期:2026-09-15
  • 决策者:毕设作者
  • 相关文档:docs/05-数据库设计.md、docs/adr/0001-dual-database-isolation.md

背景 ​

ADR-0001 决定了"双库分离",但没决定用什么数据库引擎、隔离到什么程度。毕设的现实约束是:单人开发、一台开发机、无服务器采购预算、需要现场演示(可能没有网络)。

同时,答辩必然会被问:

你说的"双库分离",是两台物理数据库实例,还是逻辑分开?

这个问题如果回答含糊,会被认为没想清楚。

决策 ​

分两阶段,同一套设计,只是隔离强度不同:

阶段business-dbai-db隔离强度
原型期(毕设)SQLite 单文件(如 data/business.sqlite)SQLite + 向量扩展 / 或 Chroma 本地持久化目录逻辑隔离:两套独立文件、独立进程、独立账号配置、独立备份策略
落地期(工业产品)PostgreSQL 实例Qdrant / Chroma 独立实例物理隔离:两台实例,可不同主机/网段

"逻辑隔离"在本项目中的精确定义(答辩时必须这样回答):

  1. 两套独立的数据库文件/实例,不是同一实例的两个 schema 共用连接;
  2. 两套完全独立的账号:business-db 账号只配置在业务接口服务与网关的进程中;ai-db 账号只配置在网关的进程中;
  3. Agent 进程中不存在任何一套的凭证;
  4. 两者的迁移脚本、种子数据、备份任务完全分开,互不引用。

理由 ​

  1. 原型期用 SQLite 的收益:零运维、单文件、可随仓库演示、可直接用 SQL 工具打开截图作为答辩证据、无需网络。毕设验证的是架构与权限边界,不是数据库吞吐能力。
  2. 逻辑隔离已足以验证课题的核心命题。"Agent 拿不到业务库凭证"这件事,与数据库是否物理分离无关——只要 Agent 的环境变量里没有连接串,隔离就成立。物理分离提高的是故障域隔离强度与运维规范度,属于落地期收益。
  3. 设计可迁移。表结构、索引策略、字段白名单在 SQLite 与 PostgreSQL 之间基本可平移,迁移成本集中在 DDL 方言与并发控制,不影响 ADR-0001 的结论。

备选方案与拒绝理由 ​

方案为什么没选
原型期直接上 PostgreSQL需要安装、起服务、配账号、管理连接池,对单机演示是纯负担;毕设答辩价值不增。
原型期直接上两套 Docker 实例做物理隔离演示环境依赖 Docker,现场风险高;且"逻辑隔离已足够"这一点反而讲不清楚。
用 MySQL + 向量插件凑成"单实例双库"两库共用同一实例 ⇒ 共用连接池与凭据管理路径,隔离论证变弱,得不偿失。
只用一个 SQLite 文件 + 表名前缀区分最省事,但"双库分离"退化成命名约定,隔离完全靠代码自律,无法支撑答辩论证。

后果 ​

正面

  • 演示环境零依赖,仓库克隆即可跑通全链路。
  • 双库的物理位置清晰可指(两个文件路径),答辩时可直接打开两个文件对比表结构,直观证明"ai-db 里没有任何业务字段"。
  • 迁移到 PostgreSQL 时,ADR-0001 与 ADR-0002 的结论不变,只需重跑迁移脚本。

负面 / 代价

  • SQLite 的并发写能力弱(单写者),遥测高频写入时会成为瓶颈。原型期通过批量写入 + WAL 模式缓解,并明确标注这是原型局限。
  • SQLite 无行级安全策略(RLS)、无原生角色权限体系,"账号分离"退化为"连接串分离 + 文件系统权限分离",隔离强度弱于 PostgreSQL。此差异必须在 docs/05-数据库设计.md 中显式标注,不能含糊带过。
  • 向量检索需要额外选型:SQLite 无原生向量索引,原型期用 Chroma 本地持久化更省事(见 docs/05-数据库设计.md)。

明确写入文档的局限说明 ​

原型期的 SQLite 双库方案,其隔离强度依赖文件系统权限 + 进程凭证分离,不具备数据库层的强制访问控制。若同机存在具有文件系统读权限的恶意进程,隔离可被绕过。落地期迁移至 PostgreSQL 后,由数据库角色权限(GRANT/REVOKE)与可选的 RLS 提供强制约束。

这段话应原样出现在 docs/05-数据库设计.md 的"局限与风险"章节,答辩时主动说明。