6.9 KiB
开发数据库 Schema 基线与版本门禁设计规格
- 功能编号:GOV-007
- 规格版本:0.1
- 状态:approved_for_review
- 日期:2026-08-13
背景与目标
数据库正式启用后,每个新应用版本开始开发前都需要一份可审计的结构起点。只保存迁移脚本不能证明开发数据库在版本开始时的真实结构,也无法发现手工改表造成的漂移。
本功能建立强制门禁:开始开发下一个语义化版本前,从开发环境数据库导出当前已发布版本的完整 Schema,规范化、校验并纳入 Git。开发流程和脚本禁止连接、读取或探测生产数据库。
版本与命名
基线按“被备份的当前已发布版本”命名,而不是即将开发的版本。例如开始开发 v0.0.6 前,封存 v0.0.5 状态:
database/schema-baselines/v0.0.5/
├── schema.sql
├── manifest.yaml
└── checksum.sha256
每个应用版本开始前都生成一次。即使 Schema 未变化,也生成新版本目录,以相同内容校验值证明没有结构漂移。
唯一允许的数据来源
- 只允许读取开发环境数据库。
- 加载开发专用本地配置,要求
APP_ENV=development。 - 数据库名固定为
a_share_analysis_dev;名称不匹配立即终止。 - 禁止通过命令参数覆盖环境类型、数据库名或传入任意 env 文件路径。
- 禁止连接、读取、探测或导出生产数据库;生产备份属于独立运维流程,不进入开发门禁。
- 推荐使用只拥有开发库结构读取和例程查看权限的专用账号,不授予生产访问能力。
即使主机名看似本地,脚本也必须验证环境和数据库名;不能只依赖地址白名单判断安全。
导出范围
使用 MySQL 5.7 客户端 mysqldump,仅导出结构,不包含任何表数据。基线必须完整包含:
- 数据库表、列、主键、索引、外键与表选项。
- 视图。
- 触发器。
- 存储过程和函数。
- Event Scheduler 事件。
导出命令必须使用 --no-data --routines --triggers --events,并使用符合 MySQL 5.7 的选项。账号凭据通过开发 env 或受控客户端配置提供,禁止出现在命令参数、日志或清单中。
规范化
原始 mysqldump 输出经过确定性规范化后才能进入 Git:
- 删除导出时间、完成时间、客户端路径等不稳定注释。
- 删除或规范化环境绑定的
DEFINER,避免恢复时绑定个人账号。 - 删除由数据增长产生的
AUTO_INCREMENT=<当前值>,保留列的自增属性。 - 统一换行符与文件末尾换行。
- 禁止把主机、端口、账号、密码或客户端配置路径写入 SQL。
- 不改变表、视图、触发器、例程和事件的业务定义。
规范化工具必须通过固定输入/输出测试证明不会误删业务 SQL。
校验与清单
manifest.yaml 至少记录:
application_version:被备份的已发布版本。git_commit:该版本标签最终指向的提交。source_environment: development。database_name: a_share_analysis_dev。- MySQL 客户端和服务端精确版本。
charset: utf8mb4。collation: utf8mb4_general_ci。- 生成时间与生成工具版本。
- 是否包含表、视图、触发器、例程和事件。
- 规范化 SQL 的 SHA-256。
checksum.sha256 使用标准格式记录 schema.sql 校验值。流程必须重新计算并验证清单、校验文件和实际 SQL 三者一致。
强制阻断条件
出现以下任一情况,不允许进入下一版本开发:
- 当前已发布版本没有 Schema 基线,且数据库已启用。
APP_ENV不是development。- 数据库名不是
a_share_analysis_dev。 - 检测到生产配置文件、生产环境标识或禁止的连接目标。
- MySQL 客户端或服务端不是 5.7.x。
- 字符集或排序规则不是
utf8mb4/utf8mb4_general_ci。 - 导出缺少视图、触发器、存储过程/函数或事件的范围声明。
- SQL 包含
DEFINER、不稳定导出注释、当前 AUTO_INCREMENT 值或疑似凭据。 - 校验值不一致、目标版本目录已存在且内容不同,或 Git 工作区存在无法解释的 Schema 改动。
禁止覆盖既有版本基线。需要修正时新增带原因的治理记录和修复提交,不静默重写已发布事实。
首次启用与未启用状态
当前 MySQL 尚未启用,因此在开发新版本前允许记录结构备份“不适用”,但必须能证明功能开关为关闭,且不得创建伪造的空 schema.sql 冒充数据库基线。
首次启用 MySQL 的版本必须:
- 通过迁移创建开发库初始结构。
- 在 MySQL 5.7 开发环境验证字符集与排序规则。
- 发布时建立首份真实 Schema 基线。
- 后续每个版本开始前严格执行本门禁。
开发流程位置
下一版本开发前顺序为:
- 确认当前已发布版本和标签提交。
- 判断 MySQL 功能开关;未启用则保存可验证的不适用记录。
- 已启用时从开发数据库导出、规范化并校验完整 Schema。
- 将当前发布版本基线作为独立中文提交推送 Gitea。
- 确认工作区干净和远程同步成功。
- 再创建下一版本 PRD、设计与功能档案,执行 GitNexus 开发前分析。
数据库迁移必须从上一基线在 MySQL 5.7 开发环境正向执行验证。禁止直接修改共享开发表代替迁移脚本。
安全边界
- Schema 基线只含结构,不含业务数据、账号数据或生产数据。
- 导出脚本不得回显秘密,也不得接受密码命令行参数。
- 开发工具和代理无权使用生产 env 或生产数据库验证功能。
- 基线提交前扫描疑似凭据、生产主机、
DEFINER和数据 INSERT。 - Schema 基线进入 Git 后视为公开给仓库使用者,任何敏感对象名称或注释都应在数据库设计阶段避免。
实施范围
GOV-007 将实现数据库目录规范、开发 env 模板扩展、确定性 SQL 规范化工具、导出/校验脚本、自动化测试、开发流程门禁和完整追溯档案。由于当前 MySQL 未启用,本功能只验证阻断逻辑、规范化固定样本和“不适用”路径,不连接任何数据库。
验收标准
- 开发流程明确每个应用版本开始前建立上一已发布版本的开发库 Schema 基线。
- 脚本只接受
development和固定开发库名,无法通过普通参数切换到生产配置。 - 导出范围包含表、视图、触发器、存储过程/函数和事件且不含数据。
- 规范化稳定移除时间注释、
DEFINER和当前 AUTO_INCREMENT 值,但保留业务 SQL。 - 清单和 SHA-256 格式可自动校验。
- MySQL 5.7、
utf8mb4、utf8mb4_general_ci不符合时阻断。 - 当前未启用 MySQL 时使用可验证“不适用”记录,不伪造空 Schema。
- 自动化测试、治理门禁、GitNexus 和双 Review 通过。
- 中文提交和对应版本标签精确推送 Gitea。