# ADR-0008:数据库归属与实例拓扑 - **状态**:已接受 - **日期**:2026-09-24 - **决策人**:技术负责人 - **相关**:任务表 A0(决策 D13);设计文档《实施设计》1.5;ADR-0007 ## 背景 ADR-0007 定了单机版用 SQLite、服务端版用 PostgreSQL,并留了一句「APS 侧数据库选型由 APS 自己定」。但它没回答三个问题:**库归谁、能不能共用一个 PostgreSQL 实例、怎么保证平台不越过 APS 直连它的库**。项目下一步既要拆数据库(B2)又要实现平台持久层(A3.7),不分清这三件事就会各写一半。 另有一处口径需要纠正:**「单机版」指客户端与平台服务在同一台机器上,不包含 APS。** APS 始终是独立系统——即使部署在同一台机器,也是独立进程、独立库、独立界面。 ## 选项 | 选项 | 做法 | 代价 | 不选的理由 | | --- | --- | --- | --- | | A 各自私有库,可共用实例 | 平台库与 APS 库各自归属;开发期共用一个 PostgreSQL 实例的两个 database | 要账号与权限隔离,并加检查 | 选定 | | B 单一共享库 | 两边的表放同一个库 | 运维最省事 | 破坏权威数据源边界:平台能读到甚至改到业务数据,门禁形同虚设 | | C 强制不同实例 | 两边各起一个 PostgreSQL | 边界最清晰 | 单机与小型部署要维护两个数据库实例,成本不必要 | ## 结论 选 A。 | 项 | 结论 | | --- | --- | | 库归属 | 平台库归平台,APS 库归 APS:各自迁移、各自备份、各自账号 | | 库内容 | 平台 7 张(项目、会话、消息、文件、审计、待确认动作、桌面授权);APS 6 张(主数据宽表、项目字典、工艺模板两表、排产执行与结果) | | 实例拓扑 | 允许共用实例:开发期一个 PostgreSQL 跑两个 database;生产按部署拓扑定,不强制分离 | | 访问规则 | **平台代码禁止直连 APS 库**,只能经 Provider 契约;反向同理,APS 不读平台库 | | 隔离方式 | 不同 database + 不同账号;平台账号对 APS 库不授予任何权限 | | 单机版 | 客户端 + 平台服务同机,平台库用 SQLite(ADR-0007);APS 仍以独立系统部署,用自己的库 | | 检查方式 | CI 扫描连接串、表名与跨库查询;出现平台侧访问 APS 表的代码即失败 | ## 影响 - **对代码**:平台持久层只碰平台库;Provider 不接数据库,只调 APS 的接口 - **对任务**:B2 按「平台 7 / APS 6」执行;A3.7 会话落库只建平台侧表;A1.6 增加跨库访问检查 - **对文档**:术语表补「单机版 / 服务端版」定义;《实施设计》1.5 的权威数据源表以此为准 - **不这么做的后果**:共用一张表会让平台绕过门禁读到业务数据,等 B2 之后想再拆就更贵 ## 遗留 - CI 跨库检查的具体实现(正则扫连接串,还是 AST 级检查)在 A1.6 定 - 生产是否分离实例:随部署拓扑在 A10 前后定,不影响代码 ## 补记(A4 落地后,2026-09-29) A0 定这份 ADR 时平台侧的表是估算(项目、会话、消息、文件、审计、待确认动作、桌面授权,共 7 张)。A3 / A4 落地后实际如下(文件与桌面授权尚未落地): | # | 表 | 用途 | 落地任务 | |-|-|-|-| | 1 | `projects` | 项目 | A1 | | 2 | `sessions` | 会话 | A3.7 | | 3 | `messages` | 消息 | A3.7 | | 4 | `idempotency_keys` | 发消息幂等键 | A3.7 | | 5 | `context_checkpoints` | 上下文检查点 | A3.8 | | 6 | `identity_bindings` | 平台用户 → 各系统账号,附带加密后的凭据密文 | A4.1 / A4.3 | | 7 | `pending_actions` | 待确认动作与执行记录(合表,不设单独的凭据表与审批事件表) | A4.4 | | 8 | `audit_log` | 审计链,只追加 | A4.5 | 结论不变:库各自私有,平台不直连 APS 库;B2 拆库时按这张清单执行。