PHPにおけるマイグレーションとは、データベースの構造変更をコードで管理する仕組みのことです。
ここでいう構造変更とは、テーブルの作成、カラムの追加や削除、インデックスの設定、外部キーの追加などを指します。
Laravelでは、こうした変更を migration class として定義し、コマンドで適用・ロールバックできます。
Doctrine Migrations でも同様に、データベース変更を履歴として管理する考え方が採用されています。
なぜマイグレーションが必要なのか
データベースの変更は、手作業でSQLを実行して進めることもできます。
ただし、そのやり方だけに頼ると、どの環境に何を反映したのか分かりにくくなり、開発メンバーごとにデータベース構造がズレる原因になります。
マイグレーションを使えば、変更内容をコードとして保存し、Gitなどで履歴を管理しながら、同じ変更を複数の環境に再現しやすくなります。
Doctrine Migrations でも、手動SQLではなく、安全にスキーマ変更を展開する方法として migrations が位置付けられています。
基本的な考え方
マイグレーションでは、通常は1つのファイルに1つの変更目的を持たせます。
たとえば、
- usersテーブルを作成する
- usersテーブルにphoneカラムを追加する
- postsテーブルにindexを追加する
といった単位で分けて管理します。
Laravelでは migration class の中に up() と down() を定義します。
up() は変更を適用する処理、down() はその変更を元に戻す処理です。
Doctrine Migrations でも、基本的には up / down を通じて変更と巻き戻しを扱います。
Laravelでのマイグレーション
Laravelでは、マイグレーションを使ってテーブル作成やカラム追加を行います。
マイグレーションは php artisan migrate で実行され、未適用のものだけが順番に反映されます。
また、Laravelは実行済みの migration をデータベース上で管理しており、どこまで適用済みかを追跡できる仕組みを持っています。
代表的なコマンドは次の通りです。
php artisan migrate
php artisan migrate:rollback
php artisan migrate:reset
php artisan migrate:refresh
php artisan migrate:fresh
それぞれの役割は概ね次のように理解できます。
migrate
未適用の migration を実行するmigrate:rollback
直近の batch をロールバックするmigrate:reset
すべての migration をロールバックするmigrate:refresh
一度すべて戻してから再度 migrate するmigrate:fresh
テーブルを削除してから migrate を実行する
特に注意したいのは、migrate:rollback は「必ず1ファイルだけ戻す」わけではないという点です。
Laravel公式では、これは最後に実行した batch をロールバックするコマンドとして説明されています。
最後の batch に複数の migration が含まれていれば、それらがまとめて戻ることがあります。
Seederとの違い
マイグレーションと混同されやすいのが Seeder です。
この2つは役割が異なります。
- Migration
テーブルやカラム、インデックスなど、データベースの構造を変更する - Seeder
初期データやテストデータ、マスタデータを投入する
つまり、マイグレーションは器を作るもので、Seederは中身を入れるものと考えると分かりやすいです。
LaravelでもSeederは別の仕組みとして用意されています。
生SQLを使うことはあるのか
あります。
Laravelには migration のための便利なAPIがありますが、すべての変更を抽象化だけで表現できるとは限りません。
そのため、実務では必要に応じて raw SQL を使うことがあります。
Doctrine Migrations でもSQLを直接扱う考え方が用意されています。
ただし、生SQLを使う場合は注意が必要です。
たとえば、MySQLでは動くSQLがPostgreSQLではそのまま使えないことがあります。
データベース製品をまたぐ可能性があるなら、できるだけ標準の migration API を使ったほうが安全です。
ロールバックは万能ではない
ここは実務でとても重要な点です。
down() が用意されているからといって、すべての変更が安全に元通りになるとは限りません。
たとえば、カラム削除やデータ変換を含む変更では、構造だけを戻せても、失われたデータそのものまでは復元できないことがあります。
さらに、DDLの扱いはデータベース製品によって異なり、トランザクションの安全性も一律ではありません。
Doctrine Migrations でも、変更内容やDBの種類によって扱いが変わることが示されています。
そのため、本番環境では
- 事前バックアップを取る
- nullableで追加してから段階的に必須化する
- 旧仕様と新仕様を一時的に共存させる
- データ移行を構造変更と分けて進める
といった慎重な進め方が重要になります。
これは公式コマンドを覚えること以上に、実務では大切な考え方です。
CakePHPとDoctrine系の位置づけ
PHPのマイグレーションはLaravelだけのものではありません。
Symfony系では Doctrine Migrations が広く使われており、データベース変更を履歴として管理するという思想は共通しています。
CakePHPでもマイグレーションは利用できますが、ここは少し注意が必要です。
古い文脈では Phinx ベースとして説明されることがありますが、CakePHP Migrations 5.x では Phinx 依存は外れており、builtin backend のみがサポートされています。
そのため、現在の説明としては「CakePHPでもマイグレーションは使えるが、現行では builtin backend を前提に考える」としておくのがより正確です。
初学者向けにわかりやすく言うと
マイグレーションとは、「データベース設計の変更履歴を、その場の手作業ではなく、再現可能なコードとして残す仕組み」です。
Web制作の感覚に近い言い方をすると、
- HTMLやCSSの変更をファイルで管理する
- WordPressテーマの修正履歴をGitで管理する
のと同じように、
- データベース構造の変更もコードファイルとして管理する
というイメージです。
まとめ
PHPマイグレーションとは、データベースのスキーマ変更をコードとして管理する仕組みです。
Laravelでは up() と down() を持つ migration class を使い、migrate や rollback などのコマンドで適用・巻き戻しを行います。
Doctrine系でも同じように、データベース変更を履歴として管理する考え方が採用されています。
ただし、運用上は注意も必要です。
rollback は単純に「1つ前のファイルを戻す」という意味ではなく、Laravelでは最後の batch を戻すのが正確です。
また、down() があるからといって、削除済みデータまで完全に元に戻せるとは限りません。
本番環境では、段階移行やバックアップを前提に、慎重に設計することが重要です。
以上、PHPマイグレーションについてでした。
最後までお読みいただき、ありがとうございました。










