スキーママイグレーション
スキーママイグレーションとは
スキーママイグレーションは、データベースのテーブル定義(スキーマ)の変更を、順番付きのファイルとして管理して適用する仕組みです。単にマイグレーションとも呼びます。
アプリケーションを開発していると「列を追加したい」「テーブルを分けたい」という変更が必ず発生します。このとき、各自が手作業で ALTER TABLE を打つと、開発・ステージング・本番の定義がずれて事故になります。マイグレーションは変更手順そのものをファイルに残し、どの環境でも同じ順序で再現できるようにします。
仕組み
マイグレーションツールは、適用済みのファイル名を管理テーブルに記録します。実行すると「まだ適用していないものだけ」を古い順に流します。
| 要素 | 役割 |
|---|---|
| マイグレーションファイル | 1回分の変更内容。日時やバージョン番号で順序が決まる |
| up(適用) | 変更を反映する処理(列の追加など) |
| down(巻き戻し) | 適用を取り消す処理(追加した列の削除など) |
| 履歴テーブル | どこまで適用済みかをデータベース自身が記録する |
-- 例: 20260401_add_last_login_to_users.sql
ALTER TABLE users ADD COLUMN last_login_at TIMESTAMP NULL;
多くの [[ORM]] にはマイグレーション機能が付属しており、モデル定義の変更からファイルを自動生成できます。
安全に変更するコツ
デプロイ中はアプリの新旧バージョンが混在するため、一度に壊す変更を避けるのが鉄則です。
- 列の追加は NULL 許可またはデフォルト値付きにして、旧バージョンでも動くようにする
- 列名の変更・削除は「新しい列を追加 → 両方に書く → 移行 → 古い列を削除」と段階に分ける
- 大きなテーブルへの ALTER はロック([[ロックとデッドロック]])で長時間止まることがある — 実行時間と影響を事前に見積もる
- 本番適用の前に必ずバックアップを取る([[バックアップとリカバリ]])。変更する対象が数テーブルなら、そこだけ [[データベースのダンプとリストア]] で退避しておくと、取得も戻しも短時間で済む
- 適用には CREATE / ALTER / DROP の権限が要る — アプリ用とは別のアカウントで流す([[データベースのユーザーと権限管理]])
この考え方は [[デプロイ戦略]] と組み合わせて、無停止リリースを成立させるための土台になります。
運用への組み込み
マイグレーションファイルはアプリのコードと同じリポジトリに入れ、[[CI/CD]] のパイプラインで自動適用するのが一般的です。「コードとスキーマが同じコミットで一致している」状態を保てるため、どのバージョンをデプロイしても定義がずれません。
初学者向けポイント
- 適用済みのマイグレーションファイルは書き換えない — 修正は新しいファイルを追加して行う
- ローカルで [[SQL]] を直接叩いて変更した場合も、必ずマイグレーションとして残す
- down(巻き戻し)は書いておくと安心だが、データを消す変更は戻せないことを理解しておく — その場合の頼りは適用前のバックアップだけです
関連技術とのつながり
- [[ORM]] — モデル定義からマイグレーションを生成する機能を備えることが多い
- [[リレーショナルデータベース]] — 変更対象となるスキーマの本体
- [[SQL]] — マイグレーションの中身は DDL(CREATE / ALTER)の SQL
- [[CI/CD]] — パイプラインに組み込んで適用を自動化する
- [[デプロイ戦略]] — 新旧バージョン混在を前提とした段階的な変更が必要になる
- [[データベースのダンプとリストア]] — 適用前の退避と、構造だけを取り出す用途で接する
Q: スキーママイグレーションを使う主な理由はどれ?
- [x] スキーマ変更を順番付きのファイルとして残し、どの環境でも同じ手順を再現するため
- [ ] データベースの検索を高速化するため
- [ ] テーブルのデータを暗号化するため
解説: 手作業の変更は環境ごとのずれを生みます。マイグレーションは変更手順をコードとして管理し再現性を確保します。
Q: マイグレーションツールが適用漏れや二重適用を防げるのはなぜ?
- [ ] ファイル名をアルファベット順に並べ替えるから
- [x] どこまで適用済みかを履歴テーブルに記録しているから
- [ ] 実行前に必ず人が確認するから
解説: 履歴テーブルに適用済みのファイルを記録し、未適用のものだけを古い順に実行します。
Q: 列名を変更するときに本文が勧めている進め方はどれ?
- [ ] 一度の変更でいきなり列名を書き換える
- [x] 新しい列を追加し、両方に書きながら移行してから古い列を削除する
- [ ] テーブルごと作り直してデータを捨てる
解説: デプロイ中は新旧バージョンが混在するため、段階を分けて旧バージョンでも動く状態を保ちます。