データベースマイグレーション戦略

本番環境のデータベーススキーマを安全に変更するための戦略とパターン

データベース運用

データベースマイグレーション戦略とは

データベースマイグレーションは、本番環境のスキーマ (テーブル構造、インデックス、カラム) を安全に変更するプロセスである。アプリケーションのデプロイと異なり、ロールバックが困難で、データ損失のリスクがある。

マイグレーションツール

ツール 言語/フレームワーク 方式
Prisma Migrate TypeScript 宣言的 (スキーマ差分)
Flyway Java バージョン管理 (SQL ファイル)
Knex.js Node.js プログラマティック
Alembic Python (SQLAlchemy) バージョン管理
golang-migrate Go SQL ファイル

Expand-Contract パターン

破壊的変更を安全に行うための 3 段階のパターン。

Phase 1 (Expand): 新カラムを追加、新旧両方に書き込み
  ALTER TABLE users ADD COLUMN email_v2 VARCHAR(255);
  → アプリは old_email と email_v2 の両方に書き込む

Phase 2 (Migrate): 既存データを移行
  UPDATE users SET email_v2 = old_email WHERE email_v2 IS NULL;

Phase 3 (Contract): 旧カラムを削除
  ALTER TABLE users DROP COLUMN old_email;
  → アプリは email_v2 のみ使用

各フェーズを別々のデプロイで行い、問題があれば途中で止められる。

DynamoDB のマイグレーション

DynamoDB はスキーマレスだが、アプリケーションレベルでのデータ構造変更は必要になる。

// バージョンフィールドで新旧フォーマットを共存
async function getUser(id: string) {
  const item = await db.get({ TableName: 'users', Key: { id } });
  if (item.schemaVersion === 1) {
    return migrateV1toV2(item); // 読み取り時に変換
  }
  return item;
}

DynamoDB では「読み取り時に変換 + 書き戻し」のパターンが一般的だ。全件一括マイグレーションは不要。

安全なマイグレーションのルール

ルール 理由
カラム追加は安全 既存のクエリに影響しない
カラム削除は危険 アプリが参照していると障害
カラム名変更は危険 実質的に削除 + 追加
NOT NULL 追加は危険 既存データが制約違反になる
インデックス追加は注意 ロック時間が長い場合がある

ロールバック戦略

  • マイグレーション前にスナップショットを取得
  • Expand-Contract パターンで段階的に変更
  • ダウンマイグレーション (逆方向の SQL) を用意
  • DynamoDB は Point-in-Time Recovery (PITR) を有効化

理論と実装の両面から学ぶなら関連書籍が参考になる。

関連用語