2026-06-28-prisma-v1-baseline-design.md 6.6 KB

Prisma V1 Baseline Migration 设计

1. 背景

当前项目的 backend/prisma/schema.prisma 已经基本代表了当前数据库的稳定结构,可以视为第一版数据库模型。但仓库中的 backend/prisma/migrations 目录存在以下问题:

  • 历史 migration 数量很少,但依赖顺序已经不健康。
  • 20260628050000_add_customer_follow_content 依赖 customer 表存在,却早于 20260628120000_add_customer_table。
  • 20260628173000_add_template_used_count 是后补增量,而用户已经手动执行过对应 SQL。
  • 当前 migration 历史更像是开发过程痕迹,而不是可长期维护的基线。

用户希望把现在这一版数据库正式收敛为“第一个稳定版本”,后续新功能再继续追加新的 migration。

2. 目标

本次调整后,需要满足以下目标:

  1. schema.prisma 继续作为当前稳定数据库结构的唯一事实来源。
  2. backend/prisma/migrations 目录只保留一条 v1 baseline migration。
  3. 这条 baseline migration 能用于新环境从零初始化数据库。
  4. 现有旧增量 migration 全部移除,不再保留开发阶段的历史痕迹。
  5. 后续数据库改动从 v1 baseline 继续追加新的增量 migration。

3. 非目标

以下内容不在本次范围内:

  1. 不保留旧 migration 的增量演进历史。
  2. 不再尝试修复旧 migration 的依赖顺序。
  3. 不修改当前数据库表结构语义,只做基线重置。
  4. 不做业务字段增删改设计。
  5. 不把 schema.prisma 回退到旧版本状态。

4. 方案选择

方案 A:保留旧 migration,只新增一个 baseline

做法:

  • 保留当前 3 条旧 migration。
  • 再新增一条 init_v1 作为“以后认这个版本”的基线。

优点:

  • 旧历史还在。

缺点:

  • 目录仍然不干净。
  • 新成员会被旧历史误导。
  • 无法真正达到“第一版稳定基线”的目标。

方案 B:删除全部旧 migration,只保留一个新的 baseline

做法:

  • 删除当前所有旧 migration。
  • 基于当前稳定 schema.prisma 与数据库设计,新增一条 init_v1。
  • 后续所有数据库变更从该基线继续新增。

优点:

  • 目录结构最干净。
  • 与“当前稳定结构就是 v1”完全一致。
  • 未来维护成本最低。

缺点:

  • 旧增量历史不再保留。

结论

采用 方案 B:删除全部旧 migration,只保留一个新的 baseline。

5. 目标目录结构

调整后,backend/prisma 的目标结构如下:

backend/prisma/
  schema.prisma
  migrations/
    20260628_init_v1/
      migration.sql

要求:

  • 不再保留:
    • 20260628050000_add_customer_follow_content
    • 20260628120000_add_customer_table
    • 20260628173000_add_template_used_count
  • migrations 目录内只保留一个 init_v1

6. Baseline 定义

6.1 基线语义

20260628_init_v1 表示当前项目第一版稳定数据库结构。

它不是增量修改脚本,而是一个完整初始化脚本,语义是:

  • 在一个空数据库中,直接创建当前版本所需的全部表结构、字段、索引和约束。

6.2 基线内容来源

baseline migration 的 SQL 内容必须与以下两处保持一致:

  1. backend/prisma/schema.prisma
  2. backend/docs/数据库设计.md

其中:

  • schema.prisma 是代码层的事实来源。
  • 数据库设计.md 用于校验字段注释、表注释和索引注释是否完整。

6.3 基线必须包含的结构

至少包含当前稳定版本中的全部核心表:

  • hairstylist_user
  • customer
  • customer_treatment_record
  • ai_hair_simulation
  • ai_hair_simulation_task
  • hair_template
  • hair_template_make_task
  • system_config

并包含:

  • 当前稳定字段定义
  • 当前稳定索引
  • 当前稳定注释
  • hair_template.used_count

7. 现有环境的处理策略

7.1 已存在数据库的前提

当前开发环境数据库已经存在,且用户已手动执行过部分 SQL。此时不能把新的 init_v1 当成一条要“重新执行建表”的 migration 直接运行到现有数据库上,否则会和已有表冲突。

7.2 仓库层与数据库层分开处理

本次设计把处理分成两层:

  • 仓库层:
    • 清理旧 migration
    • 新增 20260628_init_v1/migration.sql
  • 数据库层:
    • 将当前数据库视为已经处于 v1 baseline 状态
    • 用 Prisma 的 migration 状态对齐手段把这条 baseline 标记为已应用

7.3 对齐原则

原则上,现有开发库不需要重建,也不需要重新执行 baseline SQL。

需要做的是:

  • 确保当前数据库结构与 schema.prisma 一致
  • 确保 Prisma 侧知道 20260628_init_v1 已经是“已应用状态”

8. 实施约束

8.1 不修改稳定结构

本次重置 migration 历史时,不允许顺手修改当前数据库结构定义。schema.prisma 中现有的稳定结构应保持不变。

8.2 保留注释完整性

因为用户对 SQL 质量有明确要求,所以 baseline SQL 必须保留:

  • 表注释
  • 字段注释
  • 索引注释

不能只生成“无注释的最小 SQL”。

8.3 baseline 只作为起点

一旦 init_v1 建立完成,后续新增字段或表时:

  • 不能回头修改 init_v1
  • 必须新增新的 migration

除非未来再次明确决定整体重置数据库基线。

9. 风险与规避

风险 1:仓库中的 baseline 与当前数据库不一致

如果 migration.sql 漏了字段或索引,新环境初始化会和当前开发环境不一致。

规避方式:

  • 生成 baseline 后,对照 schema.prisma 和 数据库设计.md 做逐项校验。

风险 2:现有环境误执行 baseline SQL

如果在已有数据库上直接执行 init_v1,会因为表已存在而失败。

规避方式:

  • 本次只把 baseline 作为仓库中的初始化基线。
  • 对现有环境采用“标记为已应用”的方式对齐,而不是重新执行完整建表 SQL。

风险 3:后续开发者继续改 baseline

如果未来继续把字段直接改进 init_v1,新的迁移历史会再次失真。

规避方式:

  • 明确规定 init_v1 只代表第一版稳定结构。
  • 后续所有变更必须新增新的 migration。

10. 验收标准

本次完成后,应满足以下验收标准:

  1. backend/prisma/migrations 中只剩一个 20260628_init_v1 目录。
  2. migration.sql 能完整表达当前稳定数据库结构。
  3. migration.sql 包含 used_count 等当前稳定字段。
  4. schema.prisma 与 baseline SQL 一致。
  5. 旧 3 条 migration 不再保留。
  6. 后续数据库开发可以在 v1 baseline 之上继续新增 migration。