database-migration

Database Migration (数据库迁移)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "database-migration" with this command: npx skills add dseirz-rgb/worker/dseirz-rgb-worker-database-migration

Database Migration (数据库迁移)

🔒 核心理念: 数据库迁移是高风险操作,必须遵循严格的安全工作流。备份优先,测试先行,回滚就绪。

🔴 第一原则:永远不要直接在生产环境执行未测试的迁移

❌ 错误做法: 直接在生产数据库执行 ALTER TABLE ✅ 正确做法: 本地测试 → 预发布验证 → 生产执行 → 验证回滚

❌ 错误做法: "这只是加个字段,应该没问题" ✅ 正确做法: 任何 schema 变更都要走完整流程

When to Use This Skill

使用此技能当你需要:

  • 添加/删除/修改数据库表或字段

  • 创建或修改索引

  • 执行数据迁移(data migration)

  • 回滚失败的迁移

  • 处理破坏性变更(删除字段、修改类型)

  • 在生产环境执行 schema 变更

Not For / Boundaries

此技能不适用于:

  • 纯查询优化(不涉及 schema 变更)

  • 应用层代码修改

  • 数据库备份恢复(参考运维文档)

Quick Reference

🎯 迁移安全工作流

需求分析 → 编写迁移 → 本地测试 → 备份生产 → 执行迁移 → 验证结果 → 监控 ↓ ↓ 评估风险 失败 → 回滚

📋 迁移前必问清单

问题 目的

  1. 这是破坏性变更吗? 删除/重命名字段需要特殊处理

  2. 数据量有多大? 大表迁移需要分批执行

  3. 有没有依赖这个字段的代码? 确保代码先兼容

  4. 回滚方案是什么? 必须有可执行的回滚脚本

  5. 迁移需要多长时间? 评估是否需要维护窗口

✅ 迁移类型风险等级

操作类型 风险等级 注意事项

添加可空字段 🟢 低 最安全的操作

添加带默认值的字段 🟡 中 大表可能锁表

添加索引 🟡 中 使用 CONCURRENTLY

修改字段类型 🔴 高 可能丢失数据

删除字段 🔴 高 不可逆操作

重命名字段 🔴 高 需要代码配合

删除表 🔴 极高 必须确认无依赖

迁移安全工作流详解

Phase 1: 备份

生产环境迁移前必须备份!

Supabase 备份

方式 1: 使用 Supabase Dashboard 导出

方式 2: 使用 pg_dump

导出完整数据库

pg_dump -h <host> -U postgres -d postgres > backup_$(date +%Y%m%d_%H%M%S).sql

只导出 schema

pg_dump -h <host> -U postgres -d postgres --schema-only > schema_backup.sql

只导出特定表

pg_dump -h <host> -U postgres -d postgres -t <table_name> > table_backup.sql

Phase 2: 本地测试

1. 生成迁移文件

pnpm drizzle-kit generate

2. 检查生成的 SQL

cat drizzle/<migration_file>.sql

3. 在本地数据库测试

pnpm drizzle-kit push

4. 验证 schema 正确

pnpm drizzle-kit studio

Phase 3: 执行迁移

生产环境迁移

pnpm drizzle-kit push --config=drizzle.config.prod.ts

或使用迁移文件

pnpm drizzle-kit migrate

Phase 4: 验证结果

-- 检查表结构 \d+ <table_name>

-- 检查数据完整性 SELECT COUNT(*) FROM <table_name>;

-- 检查约束 SELECT * FROM information_schema.table_constraints WHERE table_name = '<table_name>';

Drizzle ORM 迁移指南

基本配置

// drizzle.config.ts import { defineConfig } from 'drizzle-kit';

export default defineConfig({ schema: './src/db/schema.ts', out: './drizzle', dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL!, }, });

常用命令

生成迁移文件(基于 schema 变更)

pnpm drizzle-kit generate

推送 schema 到数据库(开发环境)

pnpm drizzle-kit push

执行迁移文件(生产环境)

pnpm drizzle-kit migrate

查看数据库状态

pnpm drizzle-kit studio

检查 schema 差异

pnpm drizzle-kit check

Schema 定义示例

// src/db/schema.ts import { pgTable, text, timestamp, uuid, boolean, integer } from 'drizzle-orm/pg-core';

export const users = pgTable('users', { id: uuid('id').primaryKey().defaultRandom(), email: text('email').notNull().unique(), name: text('name'), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at').defaultNow().notNull(), });

export const posts = pgTable('posts', { id: uuid('id').primaryKey().defaultRandom(), title: text('title').notNull(), content: text('content'), authorId: uuid('author_id').references(() => users.id), published: boolean('published').default(false), viewCount: integer('view_count').default(0), createdAt: timestamp('created_at').defaultNow().notNull(), });

破坏性变更处理

删除字段的安全流程

  1. 代码中移除对该字段的所有引用
  2. 部署代码变更
  3. 等待确认无问题(建议 24-48 小时)
  4. 执行数据库迁移删除字段

重命名字段的安全流程

  1. 添加新字段
  2. 数据迁移:复制旧字段数据到新字段
  3. 代码改为使用新字段
  4. 部署代码
  5. 确认无问题后删除旧字段

修改字段类型的安全流程

  1. 添加新字段(新类型)
  2. 数据迁移:转换并复制数据
  3. 代码改为使用新字段
  4. 部署代码
  5. 确认无问题后删除旧字段

回滚策略

回滚原则

  • 每个迁移都要有对应的回滚脚本

  • 回滚脚本必须在执行迁移前测试

  • 破坏性变更的回滚需要数据恢复

回滚方式

方式 1: 使用 Drizzle 回滚

Drizzle 目前不支持自动回滚,需要手动编写

方式 2: 手动 SQL 回滚

-- 回滚添加字段 ALTER TABLE users DROP COLUMN new_field;

-- 回滚添加索引 DROP INDEX idx_users_email;

-- 回滚添加表 DROP TABLE new_table;

方式 3: 从备份恢复

恢复完整数据库

psql -h <host> -U postgres -d postgres < backup.sql

恢复特定表

psql -h <host> -U postgres -d postgres < table_backup.sql

生产环境迁移注意事项

🚨 高风险操作检查清单

  • 已创建数据库备份

  • 已在本地/预发布环境测试

  • 已准备回滚脚本

  • 已通知相关团队成员

  • 已选择低峰期执行

  • 已准备监控告警

大表迁移策略

-- 添加索引时使用 CONCURRENTLY(不锁表) CREATE INDEX CONCURRENTLY idx_users_email ON users(email);

-- 大表添加字段时分批更新默认值 -- 1. 先添加可空字段 ALTER TABLE large_table ADD COLUMN new_field TEXT;

-- 2. 分批更新数据 UPDATE large_table SET new_field = 'default' WHERE id IN (SELECT id FROM large_table WHERE new_field IS NULL LIMIT 10000);

-- 3. 最后添加 NOT NULL 约束 ALTER TABLE large_table ALTER COLUMN new_field SET NOT NULL;

零停机迁移模式

  1. 添加新字段(可空)
  2. 部署代码:同时写入新旧字段
  3. 数据迁移:填充历史数据
  4. 部署代码:只读取新字段
  5. 删除旧字段

Examples

Example 1: 添加新字段

Input: "需要给 users 表添加 avatar_url 字段"

Steps:

  • 修改 schema 文件

  • 生成迁移

  • 本地测试

  • 生产执行

Expected Output:

// src/db/schema.ts export const users = pgTable('users', { // ... 现有字段 avatarUrl: text('avatar_url'), // 新增可空字段 });

生成迁移

pnpm drizzle-kit generate

检查生成的 SQL

ALTER TABLE users ADD COLUMN avatar_url TEXT;

执行迁移

pnpm drizzle-kit push

Example 2: 安全删除字段

Input: "需要删除 users 表的 legacy_field 字段"

Steps:

  • 确认代码中无引用

  • 备份数据

  • 执行删除

Expected Output:

1. 搜索代码确认无引用

grep -r "legacy_field" src/

2. 备份该字段数据

psql -c "COPY (SELECT id, legacy_field FROM users) TO '/tmp/legacy_backup.csv' CSV HEADER;"

3. 修改 schema 移除字段

4. 生成并执行迁移

pnpm drizzle-kit generate pnpm drizzle-kit push

Example 3: 添加索引

Input: "users 表的 email 查询很慢,需要添加索引"

Steps:

  • 分析查询模式

  • 创建索引

  • 验证性能

Expected Output:

// src/db/schema.ts import { pgTable, text, index } from 'drizzle-orm/pg-core';

export const users = pgTable('users', { id: uuid('id').primaryKey(), email: text('email').notNull(), }, (table) => ({ emailIdx: index('idx_users_email').on(table.email), }));

-- 生产环境使用 CONCURRENTLY 避免锁表 CREATE INDEX CONCURRENTLY idx_users_email ON users(email);

References

  • references/drizzle-templates.md : Drizzle ORM 迁移代码模板

  • references/rollback-strategies.md : 各类迁移的回滚策略

Maintenance

  • Sources: Drizzle ORM 官方文档, PostgreSQL 最佳实践

  • Last Updated: 2025-01-01

  • Known Limits:

  • 回滚策略依赖手动编写

  • 大规模数据迁移需要额外工具支持

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

deployment-verification

No summary provided by upstream source.

Repository SourceNeeds Review
General

error-handling

No summary provided by upstream source.

Repository SourceNeeds Review
General

documentation

No summary provided by upstream source.

Repository SourceNeeds Review