name: database-migrations model: standard description: Safe, zero-downtime database migration strategies — schema evolution, rollback planning, data migration, tooling, and anti-pattern avoidance for production systems. Use when planning schema changes, writing migrations, or reviewing migration safety.
| Strategy | Risk | Downtime | Best For |
|---|---|---|---|
| Additive-Only | Very Low | None | APIs with backward-compatibility guarantees |
| Expand-Contract | Low | None | Renaming, restructuring, type changes |
| Parallel Change | Low | None | High-risk changes on critical tables |
| Lazy Migration | Medium | None | Large tables where bulk migration is too slow |
| Big Bang | High | Yes | Dev/staging or small datasets only |
Default to Additive-Only. Escalate to Expand-Contract only when you must modify or remove existing structures.
Every production migration must avoid locking tables or breaking running application code.
| Operation | Pattern | Key Constraint |
|---|---|---|
| Add column | Nullable first | Never add NOT NULL without default on large tables |
| Rename column | Expand-contract | Add new → dual-write → backfill → switch reads → drop old |
| Drop column | Deprecate first | Stop reading → stop writing → deploy → drop |
| Change type | Parallel column | Add new type → dual-write + cast → switch → drop old |
| Add index | Concurrent | CREATE INDEX CONCURRENTLY — don't wrap in transaction |
| Split table | Extract + FK | Create new → backfill → add FK → update queries → drop old columns |
| Change constraint | Two-phase | Add NOT VALID → VALIDATE CONSTRAINT separately |
| Add enum value | Append only | Never remove or rename existing values |
| Tool | Ecosystem | Style | Key Strength |
|---|---|---|---|
| Prisma Migrate | TypeScript/Node | Declarative (schema diff) | ORM integration, shadow DB |
| Knex | JavaScript/Node | Imperative (up/down) | Lightweight, flexible |
| Drizzle Kit | TypeScript/Node | Declarative (schema diff) | Type-safe, SQL-like |
| Alembic | Python | Imperative (upgrade/downgrade) | Granular control, autogenerate |
| Django Migrations | Python/Django | Declarative (model diff) | Auto-detection |
| Flyway | JVM / CLI | SQL file versioning | Simple, wide DB support |
| golang-migrate | Go / CLI | SQL (up/down files) | Minimal, embeddable |
| Atlas | Go / CLI | Declarative (HCL/SQL diff) | Schema-as-code, linting, CI |
Match the tool to your ORM and deployment pipeline. Prefer declarative for simple schemas, imperative for fine-grained data manipulation.
| Approach | When to Use |
|---|---|
| Reversible (up + down) | Schema-only changes, early-stage products |
| Forward-only (corrective migration) | Data-destructive changes, production at scale |
| Hybrid | Reversible for schema, forward-only for data |
_deprecated suffix instead of droppingCREATE TABLE _backup_<table>_<date> AS SELECT * FROM <table>pg_dump of affected tables before migration1. Replicate primary → secondary (green)
2. Apply migration to green
3. Run validation suite against green
4. Switch traffic to green
5. Keep blue as rollback target (N hours)
6. Decommission blue after confidence window
| Strategy | Best For |
|---|---|
| Inline backfill | Small tables (< 100K rows) |
| Batched backfill | Medium tables (100K–10M rows) |
| Background job | Large tables (10M+ rows) |
| Lazy backfill | When immediate consistency not required |
DO $$ DECLARE batch_size INT := 1000; rows_updated INT; BEGIN LOOP UPDATE my_table SET new_col = compute_value(old_col) WHERE id IN ( SELECT id FROM my_table WHERE new_col IS NULL LIMIT batch_size FOR UPDATE SKIP LOCKED ); GET DIAGNOSTICS rows_updated = ROW_COUNT; EXIT WHEN rows_updated = 0; PERFORM pg_sleep(0.1); -- throttle to reduce lock pressure COMMIT; END LOOP; END $$;推荐访问7w4.net获取更多AI技能。
For expand-contract and parallel change:
- name: Test migrations
steps:
- run: docker compose up -d db
- run: npm run migrate:up # apply all
- run: npm run migrate:down # rollback all
- run: npm run migrate:up # re-apply (idempotency)
- run: npm run test:integration # validate app
- run: npm run migrate:status # no pending
Every migration PR must pass: up → down → up → tests.
NOT NULL to a large table without a default value in a single statement这个技能质量不错,内容全面且实用,涵盖了数据库迁移的各种策略、工具和最佳实践,结构清晰易读。优点是提供了详细的操作清单和避坑指南,对实际工作很有帮助。不足之处是缺少针对不同数据库的具体差异说明,代码示例也不够丰富,对新手可能不够友好。