DB Migration
解决什么问题:schema 演化是状态变更——手动 ALTER 是生产事故的最大来源。迁移工具让 schema 变更可版本化、可回滚、可审计。
它是什么
DB Migration(数据库迁移) = 用版本化脚本管理 schema 变更的工具链——
- 每个迁移是一个文件(
V001__create_orders.sql/V002__add_index.sql) - 迁移有序执行,有 checksum 校验
- 工具:Flyway(Java 主流)/Liquibase(XML/YAML)/Alembic(Python)/Sqitch
SE@G Ch 7:"Schema migrations must be versioned, tested, and reversible when possible."
V2 视角(V2.7 B7 演化):schema = 系统的状态。迁移 = 状态空间的安全导航——必须可前进、可回退、可审计。
关键属性
| 属性 | 值/含义 |
|---|---|
| 形式 | 顺序版本脚本(V001 / V002 / ...) |
| 执行时机 | 应用启动前 / CI 流水线 / 独立 job |
| 回滚策略 | 补偿迁移(V001_UP / V001_DOWN)/ 蓝绿迁移 |
| 关键原则 | 前向兼容 + 向后兼容(deploy 时新旧版本共存) |
| 反模式 | 手动 ALTER / 不在 CI 跑 / 迁移无校验 |
| 核心约束 | 每次迁移必须可逆 或 显式声明不可逆(删字段) |
| 判错标准 | prod 改 schema 需要 DBA 手动执行 = 迁移失效 |
怎么用
场景 1:Flyway 迁移(Java)
-- src/main/resources/db/migration/V001__create_orders.sql
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT NOT NULL,
status VARCHAR(32) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_orders_customer ON orders(customer_id);
-- V002__add_total_amount.sql
ALTER TABLE orders ADD COLUMN total_amount NUMERIC(19, 2);应用启动:Flyway 自动检查 flyway_schema_history 表 → 跑未执行的迁移。
场景 2:零停机迁移(Expand-Contract)
问题:删除列 ALTER TABLE orders DROP COLUMN old_field 会让旧版应用崩溃。
解法:Expand-Contract 三步走
- Expand:新代码写双份(新旧字段都写)
- Migrate:回填旧数据 → 切读 → 切写
- Contract:确认无旧引用 → DROP COLUMN
V2 B7 视角:Expand-Contract = 演化中的安全过渡——永远保持前进方向可回退。
场景 3:迁移测试
测试必须包含迁移:
@Test
void migration_V002_addsTotalAmount() {
// 启动 H2 / Testcontainers
// 跑迁移 V001 → V002
// 断言 total_amount 列存在
assertTrue(schema.columnExists("orders", "total_amount"));
}V2 B5 视角:迁移测试 = 演化的反馈——上线前发现 schema 问题。
常见误区
- "迁移 = 一次性脚本"——错。迁移是永久资产——上线后必须保留,不可删除
- "迁移不需要测试"——错。迁移 bug = 全站宕机。迁移必须有测试覆盖
- "先 DROP 再 ADD"——错。DROP 不可逆——必须 Expand-Contract
- "应用启动跑迁移"——对但要小心——多实例同时启动 = 竞争条件——用 Flyway lock / 独立 job
- "迁移工具 = 数据库无关"——半错。Flyway 部分数据库支持有限——大型迁移要 native + 工具结合
关键洞察
DB Migration 是"schema 演化的安全导航"——可前进、可回退、可审计 = 控制论意义上的状态可控。
控制论视角:schema = 系统状态空间;迁移 = 状态空间的合法转移函数。没有合法转移 = 系统失稳。 IDDD Ch 12 视角:聚合的持久化 schema 是领域模型的物理映射——schema 演化 = 领域演化。 SE@G Ch 7 视角:Google 的 migration 必须经过 审查 + 灰度 + 监控——三者缺一不可。 EDM Ch 6 视角:事件 schema 演进和 DB schema 演进有相同原则——前向/后向兼容 + 版本化。
相关链接
- CI/CD——迁移在流水线中的位置
- Config & Env——DB 连接也是配置
- [V3 涌现之时] · 演化——schema 演化的安全原则
- [V3 涌现作为] · 反馈——迁移测试 = 演化的反馈
- 源典:SE@G Ch 7——大规模 schema 迁移
- 源典:EDM Ch 6——事件 schema 演进