データベースマイグレーション戦略
本番環境のデータベーススキーマを安全に変更するための戦略とパターン
データベース運用
データベースマイグレーション戦略とは
データベースマイグレーションは、本番環境のスキーマ (テーブル構造、インデックス、カラム) を安全に変更するプロセスである。アプリケーションのデプロイと異なり、ロールバックが困難で、データ損失のリスクがある。
マイグレーションツール
| ツール | 言語/フレームワーク | 方式 |
|---|---|---|
| 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) を有効化
理論と実装の両面から学ぶなら関連書籍が参考になる。