スキーママイグレーション

スキーママイグレーションとは

スキーママイグレーションは、データベースのテーブル定義(スキーマ)の変更を、順番付きのファイルとして管理して適用する仕組みです。単にマイグレーションとも呼びます。

アプリケーションを開発していると「列を追加したい」「テーブルを分けたい」という変更が必ず発生します。このとき、各自が手作業で 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] 新しい列を追加し、両方に書きながら移行してから古い列を削除する
- [ ] テーブルごと作り直してデータを捨てる
解説: デプロイ中は新旧バージョンが混在するため、段階を分けて旧バージョンでも動く状態を保ちます。