应使用带版本号的迁移工具(如flyway)管理建表SQL,命名含时间戳、禁用破坏性操作、保障幂等性;ERD须从代码/数据库自动生成并纳入CI;结构变更需加BREAKING注释、自动通知下游、分阶段清理字段。
模型建表后怎么让 SQL 变成团队可协作的代码资产
模型建表不能只停留在本地 create table 语句里。一旦多人改字段、加索引、调默认值,没有版本化管理的 sql 就会迅速变成“谁都不敢动”的黑盒。核心是把建表逻辑变成可提交、可审查、可回滚的代码——不是导出 sql 文件扔进 git,而是用迁移工具驱动变更。
实操建议:
- 用
sqlx migrate(Rust)、alembic(Python)或flyway(Java)这类带顺序版本号的迁移工具,而不是手写schema.sql全量覆盖 - 每个迁移文件名必须含时间戳+简短描述,例如
V202405211430__add_user_status_column.sql,避免init.sql或v1.sql这类无序命名 - 禁止在迁移中使用
DROP TABLE或ALTER TABLE ... RENAME TO等破坏性操作;要用CREATE TABLE IF NOT EXISTS+ 显式ADD COLUMN替代 - 所有迁移文件提交前,需在干净数据库上执行
flyway migrate和flyway repair验证幂等性
共享图纸(ERD)怎么和实际表结构保持同步不脱节
用 dbdiagram.io 或 draw.io 手动画的 ERD 图,两周后基本就失效了。真正能共享的“图纸”,得是从代码或数据库实时生成的,不是设计师产出的静态图。
实操建议:
- 用
sqlc generate或pg2jsonschema从迁移文件或 pg 直接导出 JSON Schema,再喂给mermaid-cli渲染为.mmd图——这样每次git pull后跑一遍脚本就能更新图 - 把 ERD 生成命令写进
Makefile,例如make erd,并加入 CI:PR 合并前自动检查新迁移是否导致erd.png变更 - 不要把 PNG 图片直接塞进 Git;存
schema.mmd文本源文件,用 CI 渲染后推送到文档站或 GitHub Pages - 如果用 Prisma,直接用
npx prisma db pull+npx prisma studio查看实时视图,比任何手绘图都准
多人同时写迁移时怎么避免 flyway validate 报 checksum 冲突
冲突不是因为“改了同一张表”,而是因为两个人基于同一版本(比如 V1)各自写了 V2,结果 Flyway 检测到两个 V2 的哈希值不同,直接拒绝启动。这不是数据问题,是流程卡点。
实操建议:
- 迁移文件名里的版本号必须全局唯一,推荐用
unix timestamp(如V1716302400__xxx.sql),不用自增数字 - 每天晨会同步当天要写的迁移主题,写之前先
git pull,确认没有新V*文件落地;有就立刻重命名自己的文件为更高时间戳 - 本地开发时用
flyway repair清理失败记录,但上线前必须删掉这行——生产环境禁用repair - CI 流水线里加一步:
flyway info | grep 'Pending' | wc -l,非零则报错,防止有人忘了提交迁移文件
怎么让下游服务(如 BI、离线数仓)安全感知表结构变更
BI 工程师半夜收到告警说 column "user_name" does not exist,往往是因为上游刚合并了一条删字段的迁移,却没通知任何人。结构变更不是开发内部事务,得有显式契约。
实操建议:
- 所有影响对外字段的迁移(
DROP COLUMN、RENAME COLUMN、类型变更),必须在迁移 SQL 上方加注释:-- BREAKING: user.name → user.full_name (used by metabase/dashboard_v2) - 用
pg_depend或pg_dump --schema-only+diff自动比对前后 schema,生成变更摘要,发到 Slack 频道或钉钉群 - 禁止直接删物理列;先加
DEPRECATED_user_name TEXT,跑两周观察日志无访问后再进下一轮迁移清理 - 数仓同步任务(如 Flink CDC、Debezium)要监听
pg_replication的 DDL 事件,而不是靠人肉订阅邮件
最麻烦的从来不是写对一条 ALTER TABLE,而是让所有人——包括三个月后接手的新人——一眼看出这张表经历过几次字段生死劫。留痕比完美更重要,可追溯比快更重要。










