#11 Laravel基礎

マイグレーションの応用

マイグレーションの基本を超えて

マイグレーション? データベースのテーブル構造をコードで定義・管理する仕組み。変更履歴を残せるので、チームで同じDB構造を共有しやすい。 の基本(テーブル作成・php artisan migrate)はすでに学びました。実務ではテーブルを変更する場面が多く発生します。この回では変更系のマイグレーションを中心に解説します。


カラムを追加するマイグレーション

既存テーブルに新しいカラムを追加するには、Schema::table() を使います。

php artisan make:migration add_thumbnail_to_posts_table
<?php
// 📁 database/migrations/xxxx_add_thumbnail_to_posts_table.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::table('posts', function (Blueprint $table) {
            // body カラムの後に追加
            $table->string('thumbnail')->nullable()->after('body');
        });
    }

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

after('カラム名') で挿入位置を指定できます(MySQL のみ)。


カラムの型や属性を変更する

change() メソッドでカラムを変更します。

php artisan make:migration change_title_length_in_posts_table
// 📁 database/migrations/xxxx_change_title_length_in_posts_table.php

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        // title を 100文字から 255文字に変更
        $table->string('title', 255)->change();
    });
}

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

カラムをリネームする

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->renameColumn('body', 'content'); // body → content に改名
    });
}

インデックスを追加する

検索で頻繁に使うカラムにはインデックスを追加するとSQLが速くなります。

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->index('status');              // 単独インデックス
        $table->index(['status', 'user_id']); // 複合インデックス
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropIndex(['status']);
        $table->dropIndex(['status', 'user_id']);
    });
}

ユニーク制約を追加する

同じ値が入らないようにするユニーク制約:

public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        $table->unique('email'); // email は重複不可
    });
}

複合ユニーク(組み合わせで一意):

public function up(): void
{
    Schema::table('post_tag', function (Blueprint $table) {
        // post_id と tag_id の組み合わせで一意
        $table->unique(['post_id', 'tag_id']);
    });
}

よく使うカラム型のチートシート

メソッドDBの型使いどころ
id()BIGINT UNSIGNED AI主キー(自動採番)
string('name', 100)VARCHAR(100)短いテキスト
text('body')TEXT長文
integer('count')INT整数
unsignedBigInteger('user_id')BIGINT UNSIGNED外部キー用
boolean('is_active')TINYINT(1)フラグ
decimal('price', 8, 2)DECIMAL(8,2)金額
date('birth_date')DATE日付のみ
dateTime('published_at')DATETIME日時
timestamp('verified_at')TIMESTAMPタイムスタンプ
json('metadata')JSONJSON データ
enum('status', ['draft','published'])ENUM選択肢が固定
nullable()NULL 許容省略可能な項目
default(0)デフォルト値省略時の初期値

ロールバック

# 直前のマイグレーションを元に戻す
php artisan migrate:rollback

# 指定したステップ数だけ戻す
php artisan migrate:rollback --step=3

# すべてのマイグレーションを戻す
php artisan migrate:reset

# 全部戻してから再度適用(開発中のリセット)
php artisan migrate:fresh

⚠️ migrate:fresh はテーブルをすべて削除して作り直します。本番では絶対に使わないでください。


まとめ

  • テーブル変更は Schema::table() を使う(Schema::create() は新規作成のみ)
  • change() でカラムの定義を変更できる
  • index() で検索を速くするインデックスを追加できる
  • unique() でデータの重複を防ぐ制約を追加できる
  • down() には必ず逆の操作を書く(ロールバックのため)

次回はファクトリーとシーダーを使ったテストデータの生成を学びます。