数据库迁移模式
为生产系统提供安全、可逆的数据库模式变更。
何时激活
- 创建或修改数据库表
- 添加/删除列或索引
- 运行数据迁移(回填、转换)
- 计划零停机模式变更
- 为新项目设置迁移工具
核心原则
- 每个变更都是一次迁移 — 切勿手动更改生产数据库
- 迁移在生产环境中是只进不退的 — 回滚使用新的前向迁移
- 模式迁移和数据迁移是分开的 — 切勿在一个迁移中混合 DDL 和 DML
- 针对生产规模的数据测试迁移 — 适用于 100 行的迁移可能在 1000 万行时锁定
- 迁移一旦部署就是不可变的 — 切勿编辑已在生产中运行的迁移
迁移安全检查清单
应用任何迁移之前:
- [ ] 迁移同时包含 UP 和 DOWN(或明确标记为不可逆)
- [ ] 对大表没有全表锁(使用并发操作)
- [ ] 新列有默认值或可为空(切勿添加没有默认值的 NOT NULL)
- [ ] 索引是并发创建的(对于现有表,不与 CREATE TABLE 内联创建)
- [ ] 数据回填是与模式变更分开的迁移
- [ ] 已针对生产数据副本进行测试
- [ ] 回滚计划已记录
PostgreSQL 模式
安全地添加列
-- GOOD: Nullable column, no lock
ALTER TABLE users ADD COLUMN avatar_url TEXT;
-- GOOD: Column with default (Postgres 11+ is instant, no rewrite)
ALTER TABLE users ADD COLUMN is_active BOOLEAN NOT NULL DEFAULT true;
-- BAD: NOT NULL without default on existing table (requires full rewrite)
ALTER TABLE users ADD COLUMN role TEXT NOT NULL;
-- This locks the table and rewrites every row
无停机添加索引
-- BAD: Blocks writes on large tables
CREATE INDEX idx_users_email ON users (email);
-- GOOD: Non-blocking, allows concurrent writes
CREATE INDEX CONCURRENTLY idx_users_email ON users (email);
-- Note: C…