database-migration について
本番環境のスキーマやデータの変更を計画するエンジニア向けのデータベース移行スキルです。後方互換性と段階的な変更を重視し、テスト、ロールバック、問題の診断も扱います。
主な機能
- 01後方互換性のあるスキーマ変更
- 02段階的な拡張・縮小パターン
- 03ロールバックと復旧の指針
- 04マイグレーションのテスト手法
- 05判断ツリーとトラブルシューティング
活用シーン
- 01ゼロダウンタイムのスキーマ変更計画
- 02データベース列の名前や型の変更
- 03マイグレーションのロールバック準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bobmatnyc/ claude-mpm-skills --skill database-migrationインストール後、Claude Code で/database-migrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonreferences/decision-trees.mdtroubleshooting.md詳細
データベースのマイグレーション
本番環境でデータベーススキーマを安全に進化させるためのパターンです。
マイグレーションの原則
- 後方互換性 - 新しいコードが古いスキーマでも動作する
- 可逆性 - 必要に応じてロールバックできる
- テスト済み - 本番環境に適用する前にステージング環境で検証する
- 段階的 - 大規模な一括変更ではなく、小さな変更を行う
- ダウンタイムゼロ - サービスを中断しない
安全なマイグレーションパターン
フェーズ 1:新しいものを追加する(互換性を保つ)
-- Add new column (nullable initially)
ALTER TABLE users ADD COLUMN full_name VARCHAR(255) NULL;
-- Deploy new code that writes to both old and new
UPDATE users SET full_name = CONCAT(first_name, ' ', last_name);
フェーズ 2:データを移行する
-- Backfill existing data
UPDATE users
SET full_name = CONCAT(first_name, ' ', last_name)
WHERE full_name IS NULL;
フェーズ 3:必須にする
-- Make column required
ALTER TABLE users ALTER COLUMN full_name SET NOT NULL;
フェーズ 4:古いものを削除する(新しいコードのデプロイ後)
-- Remove old columns
ALTER TABLE users DROP COLUMN first_name;
ALTER TABLE users DROP COLUMN last_name;
よくあるマイグレーション
インデックスの追加
-- Create index concurrently (PostgreSQL)
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
カラム名の変更
-- Phase 1: Add new column
ALTER TABLE users ADD COLUMN email_address VARCHAR(255);
-- Phase 2: Copy data
UPDATE users SET email_address = email;
-- Phase 3: Drop old column (after deploy)
ALTER TABLE users DROP COLUMN email;
カラム型の変更
-- Phase 1: Add new column with new type
ALTER TABLE products ADD COLUMN price_cents INTEGER;
-- Phase 2: Migrate data
UPDATE products SET price_cents = CAST(price * 100 AS INTEGER);
-- Phase 3: Drop old column
ALTER TABLE products DROP COLUMN price;
ALTER TABLE products RENAME COLUMN price_cents TO price;
外部キーの追加
-- Add column first
ALTER TABLE orders ADD COLUMN user_id INTEGER NULL;
-- Populate data
UPDATE orders SET user_id = (
SELECT id FROM users WHERE users.email = orders.user_email
);
-- Add foreign key
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id);
マイグレーションツール
Python(Alembic)
# Generate migration
alembic revision --autogenerate -m "add user full_name"
# Apply migration
alembic upgrade head
# Rollback
alembic downgrade -1
JavaScript(Knex)
// Create migration
knex migrate:make add_full_name
// Apply migrations
knex migrate:latest
// Rollback
knex migrate:rollback
Rails
# Generate migration
rails generate migration AddFullNameToUsers full_name:string
# Run migrations
rails db:migrate
# Rollback
rails db:rollback
マイグレーションのテスト
def test_migration_forward_backward():
# Apply migration
apply_migration("add_full_name")
# Verify schema
assert column_exists("users", "full_name")
# Rollback
rollback_migration()
# Verify rollback
assert not column_exists("users", "full_name")
危険な操作
❌ 本番環境では避ける
-- Locks table for long time
ALTER TABLE users ADD COLUMN email VARCHAR(255) NOT NULL;
-- Can't rollback
DROP TABLE old_users;
-- Breaks existing code immediately
ALTER TABLE users DROP COLUMN email;
✅ 安全な代替策
-- Add as nullable first
ALTER TABLE users ADD COLUMN email VARCHAR(255) NULL;
-- Rename instead of drop
ALTER TABLE old_users RENAME TO archived_users;
-- Keep old column until new code deployed
-- (multi-phase approach)
ロールバック戦略
-- Every migration needs DOWN
-- UP
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
-- DOWN
ALTER TABLE users DROP COLUMN full_name;
判断のサポート
迅速な判断ガイド
スキーマを変更しますか?
- 破壊的変更(データを削除/変更する)→ 多段階マイグレーション(拡張・縮小)
- 追加的変更(新しいカラム/テーブル)→ 単一フェーズのマイグレーション
- 大規模なテーブル(数百万行)→ インデックスには CONCURRENTLY を使用
ダウンタイムゼロが必要ですか?
- スキーマ変更 → 拡張・縮小パターン(5 フェーズ)
- データ移行(1 万行未満)→ マイグレーション内で同期的に実行
- データ移行(100 万行超)→ バックグラウンドワーカーパターン
ロールバックを計画していますか?
- 新しいスキーマを追加しただけ → シンプルな DOWN マイグレーション
- スキーマを変更/削除した → 多段階ロールバックまたは前方修正
- データを失えない → ポイントインタイムリカバリー(PITR)
マイグレーションツールを選んでいますか?
- Python/Django → Django Migrations
- Python/SQLAlchemy → Alembic
- Node.js/TypeScript → Prisma Migrate または Knex.js
- エンタープライズ/複数言語 → Flyway または Liquibase
→ 包括的な判断フレームワークについては、references/decision-trees.md を参照してください
トラブルシューティング
よくある問題のクイックリファレンス
マイグレーションが途中で失敗した → データベースの状態を確認し、修復マイグレーションで前方修正する
スキーマのずれが検出された → 自動生成を使って調整用マイグレーションを作成する
ロールバックできない(ダウングレードがない) → 逆方向のマイグレーションを作成するか、前方修正する
外部キー制約違反 → 制約を追加する前にデータを整理するか、NOT VALID として追加する
マイグレーションがテーブルを長時間ロックする → CONCURRENTLY を使用し、カラムを段階的に追加して、更新をバッチ処理する
循環依存 → マージマイグレーションを作成するか、依存関係の順序を変更する
→ 例を含む詳しい解決策については、references/troubleshooting.md を参照してください
ナビゲーション
詳細なリファレンス
-
🌳 判断ツリー - スキーママイグレーション戦略、ダウンタイムゼロのパターン、ロールバック戦略、マイグレーションツールの選択、データ移行の方法を説明します。マイグレーションを計画するときや戦略を選ぶときに読み込んでください。
-
🔧 トラブルシューティング - マイグレーション失敗からの復旧、スキーマのずれの検出、マイグレーションの競合、ロールバックの失敗、データ整合性の問題、パフォーマンスの問題について説明します。マイグレーションの問題をデバッグするときに読み込んでください。
忘れずに
- 本番データのコピーでマイグレーションをテストする
- ロールバック計画を用意しておく
- デプロイ中に監視する
- スキーマ変更についてチームと共有する
- マイグレーションを小さく、目的に集中させる