【Laravel】マイグレーション完全ガイド|作成・実行・ロールバック・カラム変更まで徹底解説

Laravel入門基本文法・構文ガイド

Laravel開発においてデータベース構造(スキーマ)を定義・管理するために欠かせないのがマイグレーション(Migration)機能です。

「SQLを手動で実行してテーブルを作成・変更している」「チーム開発で誰がどのカラムを追加したか分からなくなる」「本番環境へのDB反映でミスが起きた」といった課題は、マイグレーションを正しく使いこなすことで一掃できます。

本記事では、Laravelのマイグレーションの仕組みから、ファイルの作成・スキーマ定義・実行・ロールバック・カラム変更・実務でのベストプラクティスまで、初心者にもわかりやすく徹底解説します(Laravel 11 / 12 対応)。

  1. 1. Laravelのマイグレーションとは?仕組みとメリット
    1. マイグレーションを使う4つのメリット
    2. migrations テーブルの役割
  2. 2. 事前準備:データベース接続の設定
  3. 3. マイグレーションファイルの作成方法(make:migration)
    1. 新規テーブル作成用のファイルを生成する
    2. 既存テーブル変更用のファイルを生成する
    3. マイグレーションファイルの構造
  4. 4. テーブル定義の基本:よく使うカラム型と修飾子
    1. よく使うカラム型一覧
    2. カラム修飾子(属性の設定)
    3. 外部キー制約の書き方
  5. 5. マイグレーションの実行(php artisan migrate)
    1. 便利な実行オプション
  6. 6. マイグレーションのロールバックとリセット
    1. 直前のマイグレーションを取り消す(migrate:rollback)
    2. 開発環境を一発で初期化する(migrate:fresh)
    3. マイグレーション管理コマンド比較表
  7. 7. カラムの追加・変更・リネーム・削除(実践テクニック)
    1. ① カラムを追加する
    2. ② カラムの型や属性を変更する(change)
    3. ③ カラム名を変更する(renameColumn)
    4. ④ カラムを削除する(dropColumn)
  8. 8. マイグレーションの適用状態を確認する(migrate:status)
  9. 9. 実務で失敗しないためのベストプラクティス
  10. 10. よくあるエラーと原因・対処法
  11. まとめ:マイグレーションをマスターして安全なDB管理を
  12. 関連リファレンス記事
  13. 関連記事

1. Laravelのマイグレーションとは?仕組みとメリット

マイグレーションとは、一言で言えば「データベーススキーマのバージョン管理システム(GitのDB版)」です。

通常、テーブルの作成やカラム変更はSQL文(CREATE TABLEALTER TABLE)で行いますが、LaravelではPHPコードでスキーマを定義し、Artisanコマンド1つでデータベースに反映できます。

マイグレーションを使う4つのメリット

  • チーム全体でスキーマを完全同期できる: Gitでマイグレーションファイルを共有し、php artisan migrate を実行するだけで、全開発者のローカル環境が同じ状態になります。
  • 変更履歴がコードとして残る: 誰がいつどんなテーブルやカラムを追加・変更したかがファイルとして記録されます。
  • 安全にロールバック(巻き戻し)ができる: 変更前の状態に戻す down メソッドを用意しておくことで、トラブル時に直前の状態へ即座に切り戻せます。
  • DBエンジンに依存しない記述: MySQL、PostgreSQL、SQLite、SQL Serverなど、異なるRDBMSでも同じPHPコードでスキーマを構築できます。

migrations テーブルの役割

Laravelはマイグレーションを実行すると、データベース内に自動的に migrations という管理テーブルを作成します。

このテーブルには「実行済みのマイグレーションファイル名」と「実行バッチ番号(batch)」が記録されます。Laravelはここを参照することで、「まだ適用されていない新しいマイグレーションファイルだけ」を自動判別して実行します。

2. 事前準備:データベース接続の設定

マイグレーションを実行する前に、プロジェクトルートの .env ファイルでデータベース接続情報が正しく設定されているか確認します。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_laravel_app
DB_USERNAME=root
DB_PASSWORD=secret

※ SQLiteを使用する場合は DB_CONNECTION=sqlite とし、database/database.sqlite ファイルを作成しておくだけで利用可能です。

3. マイグレーションファイルの作成方法(make:migration)

マイグレーションファイルを新規作成するには、Artisanコマンドの make:migration を使用します。

新規テーブル作成用のファイルを生成する

php artisan make:migration create_posts_table

ファイル名が create_テーブル名_table の形式になっていると、Laravelは自動的にテーブル作成用のスケルトンコードを生成してくれます。

既存テーブル変更用のファイルを生成する

すでに存在するテーブルにカラムを追加・変更する場合は、--table オプションを指定します。

php artisan make:migration add_status_to_posts_table --table=posts

マイグレーションファイルの構造

生成されたファイルは database/migrations/2026_01_01_000000_create_posts_table.php のように、先頭に実行日時プレフィックスが付与されます。Laravel 11以降では以下のような「無名クラス(Anonymous Migration)」の構文が標準です。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * マイグレーションの実行(適用)
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

    /**
     * マイグレーションのロールバック(巻き戻し)
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
  • up() メソッド: php artisan migrate 実行時に呼び出される処理(テーブル作成やカラム追加など)を記述します。
  • down() メソッド: php artisan migrate:rollback 実行時に呼び出される処理(テーブル削除やカラム削除など、up() の逆操作)を記述します。

4. テーブル定義の基本:よく使うカラム型と修飾子

Blueprint $table オブジェクトを使用して、テーブルのカラム定義を行います。

よく使うカラム型一覧

メソッド生成される型(MySQL例)用途・説明
$table->id();BIGINT AUTO_INCREMENT (PK)自動増分の主キー(id カラム)
$table->string('title', 100);VARCHAR(100)短い文字列(第2引数で長さ指定可能。省略時は255)
$table->text('content');TEXT長文テキスト(記事本文など)
$table->integer('views');INT整数値
$table->unsignedBigInteger('user_id');BIGINT UNSIGNED符号なし大きな整数(外部キーなど)
$table->boolean('is_published');TINYINT(1) / BOOLEAN真偽値(フラグ)
$table->decimal('price', 10, 2);DECIMAL(10, 2)固定小数点数(金額など)
$table->date('published_at');DATE日付(YYYY-MM-DD)
$table->dateTime('reserved_at');DATETIME日時(YYYY-MM-DD HH:MM:SS)
$table->json('settings');JSONJSONデータ
$table->timestamps();TIMESTAMPcreated_atupdated_at を自動生成
$table->softDeletes();TIMESTAMP (nullable)論理削除用の deleted_at を生成

カラム修飾子(属性の設定)

カラム型の後ろにメソッドチェーンをつなぐことで、NULL許容やデフォルト値などの属性を設定できます。

// NULLを許可する
$table->string('sub_title')->nullable();

// デフォルト値を設定する
$table->string('status')->default('draft');
$table->integer('priority')->default(0);

// ユニーク制約(一意)を付与する
$table->string('email')->unique();

// 特定カラムの後ろに配置する(MySQLのみ)
$table->string('phone')->after('email');

// カラムにコメントを付与する
$table->string('code')->comment('商品コード');

外部キー制約の書き方

Laravelでは foreignId メソッドを使うことで、簡潔かつ安全に外部キー制約を定義できます。

// usersテーブルのidを参照する外部キー(CASCADE削除付き)
$table->foreignId('user_id')
      ->constrained()
      ->cascadeOnDelete();

constrained() を引数なしで呼ぶと、カラム名(user_id)から自動的に参照先テーブル(users)とカラム(id)を推測してくれます。親レコード削除時に連動して削除する場合は cascadeOnDelete()、NULLにする場合は nullOnDelete() を指定します。

5. マイグレーションの実行(php artisan migrate)

マイグレーションファイルを記述したら、データベースに反映します。

php artisan migrate

未適用のファイルが順番に実行され、ターミナルに以下のような実行結果が出力されます。

Running migrations.
2026_01_01_000000_create_posts_table ........................... 15.20ms DONE

便利な実行オプション

  • SQLを事前確認する(--pretend:
    php artisan migrate --pretend
    実際にクエリを実行せず、発行される生SQL文を画面に表示します。安全確認に便利です。
  • マイグレーション後に初期データを投入する(--seed:
    php artisan migrate --seed
    マイグレーション完了後、自動的に Seeder を実行します。
  • 本番環境で確認なしに強制実行する(--force:
    php artisan migrate --force
    本番環境(APP_ENV=production)では確認プロンプトが表示されるため、CI/CDパイプラインや自動デプロイスクリプトでは --force が必須です。

※ コマンドの詳細なオプション仕様は php artisan migrate の使い方とオプション一覧 も参照してください。

6. マイグレーションのロールバックとリセット

マイグレーションの実行を取り消したい、または環境を作り直したい場合に使用するコマンド群です。

直前のマイグレーションを取り消す(migrate:rollback)

# 直近1回(1バッチ)のマイグレーションをロールバック
php artisan migrate:rollback

# 直近3つのマイグレーションファイルをロールバック
php artisan migrate:rollback --step=3

migrate:rollback は、最後に実行されたバッチに含まれるマイグレーションの down() メソッドを実行します。詳細な挙動は migrate:rollbackの使い方ガイド をご確認ください。

開発環境を一発で初期化する(migrate:fresh)

ローカル開発中にスキーマを一から作り直したい場合、最もよく使われるのが migrate:fresh です。

# 全テーブルをDROPして全マイグレーションを再実行
php artisan migrate:fresh

# テストデータ(Seeder)も一緒に投入
php artisan migrate:fresh --seed

マイグレーション管理コマンド比較表

コマンド動作内容主な使用シーン
migrate未適用のマイグレーションを実行通常のスキーマ更新、本番デプロイ
migrate:rollback直前バッチの down() を実行して取り消しミスしたマイグレーションの切り戻し
migrate:fresh全テーブルをDROP してから全実行ローカル開発でのDBリフレッシュ(推奨)
migrate:refreshすべての down() を実行後に全実行down() の動作検証
migrate:resetすべての down() を実行(再実行はしない)DBを空に戻したいとき
migrate:statusマイグレーションの適用状態を一覧表示未適用の確認、トラブル調査

7. カラムの追加・変更・リネーム・削除(実践テクニック)

本番稼働後やチーム開発では、既存テーブルを変更するマイグレーションが日常的に発生します。必ず Schema::table を使用して新しいマイグレーションファイルを作成します。

① カラムを追加する

php artisan make:migration add_published_at_to_posts_table --table=posts
public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dateTime('published_at')->nullable()->after('content');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropColumn('published_at');
    });
}

② カラムの型や属性を変更する(change)

既存カラムのサイズ拡張やNULL許容化を行うには、change() メソッドを使います。

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        // title の長さを 255 から 500 に拡張し、nullable に変更
        $table->string('title', 500)->nullable()->change();
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        // 元の定義(NOT NULL、長さ255)に戻す
        $table->string('title', 255)->nullable(false)->change();
    });
}

💡 Laravel 11 / 12 のポイント:
以前のLaravelでは change() の利用に doctrine/dbal パッケージが必須でしたが、Laravel 11以降はフレームワーク標準でカラム変更をサポートするようになり、追加パッケージのインストールが不要になりました。

③ カラム名を変更する(renameColumn)

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->renameColumn('title', 'post_title');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->renameColumn('post_title', 'title');
    });
}

④ カラムを削除する(dropColumn)

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropColumn('is_draft');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        // ロールバック時にカラムを復元する
        $table->boolean('is_draft')->default(true);
    });
}

8. マイグレーションの適用状態を確認する(migrate:status)

現在どのマイグレーションが適用済みで、どれが未適用かを確認するには migrate:status を実行します。

php artisan migrate:status
+------+-------------------------------------------------------+-------+
| Ran? | Migration                                             | Batch |
+------+-------------------------------------------------------+-------+
| Yes  | 2026_01_01_000000_create_users_table                  | 1     |
| Yes  | 2026_01_01_000001_create_posts_table                  | 1     |
| No   | 2026_01_02_000000_add_published_at_to_posts_table     |       |
+------+-------------------------------------------------------+-------+

Ran?No になっているファイルが、次回 php artisan migrate 実行時に適用されるマイグレーションです。

9. 実務で失敗しないためのベストプラクティス

  1. 適用済みのマイグレーションファイルを直接編集しない
    すでにGitにプッシュしたり本番環境に適用したファイルを書き換えても、migrations テーブルに記録済みのマイグレーションは再実行されません。スキーマを変更したいときは、必ず新しいマイグレーションファイルを作成してください。
  2. down() メソッドを必ず実装する
    カラム追加やテーブル作成を行った際は、対になるロールバック処理(dropColumndropIfExists)を必ず down() に書いておきましょう。これが抜けていると、デプロイ失敗時の緊急切り戻しができなくなります。
  3. 本番運用の大規模テーブル変更はロックに注意する
    何百万件ものデータがあるテーブルに対して ALTER TABLE を実行すると、テーブルロックが発生してWebサービスが一時停止する恐れがあります。事前に実行計画や所要時間を確認し、段階的な移行(カラム追加 → アプリ側切り替え → 旧カラム削除)を行いましょう。
  4. 外部キーの型と符号(unsigned)を一致させる
    主キーが $table->id()(BIGINT UNSIGNED)の場合、参照側の外部キーも $table->foreignId('user_id')$table->unsignedBigInteger('user_id') で型と符号を完全に一致させる必要があります。

10. よくあるエラーと原因・対処法

エラーメッセージ主な原因対処法
Base table or view already exists作成しようとしたテーブルが既にDBに存在するDBを手動操作したか、ファイルが重複。migrate:status を確認し、不要ならテーブルを削除するか Schema::hasTable で存在判定を追加。
Column already exists追加しようとしたカラムが既にテーブルに存在する過去に直接カラムを追加していないか確認。新規マイグレーションの定義を見直す。
Foreign key constraint is incorrectly formed外部キーの型不一致、または参照先テーブルが未作成マイグレーションファイルの実行順序(タイムスタンプ)を確認し、親テーブルが先に作られるように調整。型の符号(unsigned)を一致させる。
SQLSTATE[HY000] [1049] Unknown database指定されたデータベースが存在しない.envDB_DATABASE 設定を確認し、DBサーバー上にデータベースを作成する。
Nothing to migrate.未適用のマイグレーションが存在しない全ファイルが適用済みです。新しいファイルを作ったのに反映されない場合は、配置ディレクトリやファイル名を確認。

まとめ:マイグレーションをマスターして安全なDB管理を

Laravelのマイグレーションは、チーム開発や本番運用におけるデータベース管理を安全かつ効率的に行うための基盤です。

  • ファイルの作成は php artisan make:migration
  • 適用の実行は php artisan migrate
  • 切り戻しは php artisan migrate:rollback
  • ローカル開発のリフレッシュは php artisan migrate:fresh --seed
  • 既存テーブルの変更は Schema::tablechange()

それぞれのコマンドの役割と up() / down() の関係性をしっかり押さえて、日々のLaravel開発に役立ててください。

関連リファレンス記事

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする

コメント