Skip to content

データベース: マイグレーション

はじめに

マイグレーションはデータベースのバージョン管理のようなもので、チームがアプリケーションのデータベーススキーマ定義を共有し、変更を加えることを可能にします。ソース管理から変更を取り込んだ後、チームメイトに手動でローカルデータベーススキーマにカラムを追加するように伝える必要があったことがあるなら、データベースマイグレーションが解決する問題に直面したことになります。

LaravelのSchema ファサードは、Laravelがサポートするすべてのデータベースシステムに対して、テーブルの作成と操作をデータベースに依存しない形で提供します。通常、マイグレーションはこのファサードを使用して、データベーステーブルとカラムを作成および変更します。

マイグレーションの生成

データベースマイグレーションを生成するには、make:migration Artisanコマンドを使用します。新しいマイグレーションはdatabase/migrationsディレクトリに配置されます。各マイグレーションファイル名にはタイムスタンプが含まれており、Laravelはこれを使用してマイグレーションの順序を決定します。

php artisan make:migration create_flights_table

Laravelはマイグレーション名を使用して、テーブル名とマイグレーションが新しいテーブルを作成するかどうかを推測しようとします。Laravelがマイグレーション名からテーブル名を推測できる場合、Laravelは生成されたマイグレーションファイルに指定されたテーブルを事前に入力します。それ以外の場合は、マイグレーションファイルでテーブルを手動で指定するだけです。

生成されたマイグレーションのカスタムパスを指定したい場合は、make:migrationコマンドを実行する際に--pathオプションを使用できます。指定されたパスは、アプリケーションのベースパスからの相対パスである必要があります。

Note

マイグレーションスタブは、スタブの公開を使用してカスタマイズできます。

マイグレーションの圧縮

アプリケーションを構築するにつれて、時間の経過とともにマイグレーションが増えていく可能性があります。これにより、database/migrationsディレクトリが数百のマイグレーションで肥大化する可能性があります。必要に応じて、マイグレーションを1つのSQLファイルに「圧縮」することができます。開始するには、schema:dumpコマンドを実行します。

php artisan schema:dump

# 現在のデータベーススキーマをダンプし、既存のすべてのマイグレーションを削除する...
php artisan schema:dump --prune

このコマンドを実行すると、Laravelはアプリケーションのdatabase/schemaディレクトリに「スキーマ」ファイルを書き込みます。スキーマファイルの名前は、データベース接続に対応します。これで、データベースをマイグレーションしようとしても、他のマイグレーションが実行されていない場合、Laravelは最初に使用しているデータベース接続のスキーマファイル内のSQL文を実行します。スキーマファイルのSQL文が実行された後、Laravelはスキーマダンプの一部ではなかった残りのマイグレーションを実行します。

アプリケーションのテストが、ローカル開発中に通常使用するものとは異なるデータベース接続を使用している場合、そのデータベース接続を使用してスキーマファイルをダンプしていることを確認する必要があります。これにより、テストがデータベースを構築できるようになります。ローカル開発中に通常使用するデータベース接続をダンプした後に、これを行うことをお勧めします。

php artisan schema:dump
php artisan schema:dump --database=testing --prune

データベーススキーマファイルをソース管理にコミットして、チームの他の新しい開発者がアプリケーションの初期データベース構造をすばやく作成できるようにする必要があります。

Warning

マイグレーションの圧縮は、MariaDB、MySQL、PostgreSQL、およびSQLiteデータベースでのみ利用可能であり、データベースのコマンドラインクライアントを利用します。

マイグレーションの構造

マイグレーションクラスには、updownの2つのメソッドが含まれています。upメソッドは、データベースに新しいテーブル、カラム、またはインデックスを追加するために使用され、downメソッドはupメソッドによって実行された操作を元に戻す必要があります。

これらのメソッドの両方で、Laravelのスキーマビルダを使用して、テーブルの作成と変更を表現的に行うことができます。Schemaビルダで利用可能なすべてのメソッドについては、そのドキュメントを参照してください。例えば、次のマイグレーションはflightsテーブルを作成します。

<?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('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * マイグレーションを元に戻す。
     */
    public function down(): void
    {
        Schema::drop('flights');
    }
};

マイグレーション接続の設定

マイグレーションがアプリケーションのデフォルトのデータベース接続以外のデータベース接続と対話する場合、マイグレーションの$connectionプロパティを設定する必要があります。

/**
 * マイグレーションで使用するデータベース接続。
 *
 * @var string
 */
protected $connection = 'pgsql';

/**
 * マイグレーションを実行する。
 */
public function up(): void
{
    // ...
}

マイグレーションの実行

保留中のすべてのマイグレーションを実行するには、migrate Artisanコマンドを実行します。

php artisan migrate

これまでに実行されたマイグレーションを確認したい場合は、migrate:status Artisanコマンドを使用できます。

php artisan migrate:status

マイグレーションが実行されるSQL文を実際に実行せずに確認したい場合は、migrateコマンドに--pretendフラグを指定できます。

php artisan migrate --pretend

マイグレーション実行の分離

アプリケーションを複数のサーバーにデプロイし、デプロイプロセスの一部としてマイグレーションを実行する場合、2つのサーバーが同時にデータベースをマイグレーションしようとしないようにする必要があります。これを回避するには、migrateコマンドを呼び出す際にisolatedオプションを使用できます。

isolatedオプションが提供されると、Laravelはアプリケーションのキャッシュドライバを使用してアトミックロックを取得し、マイグレーションの実行を試みる前に保持します。そのロックが保持されている間にmigrateコマンドを実行しようとする他のすべての試みは実行されません。ただし、コマンドは成功した終了ステータスコードで終了します。

php artisan migrate --isolated

Warning

この機能を利用するには、アプリケーションがmemcachedredisdynamodbdatabasefile、またはarrayキャッシュドライバをアプリケーションのデフォルトキャッシュドライバとして使用する必要があります。さらに、すべてのサーバーが同じ中央キャッシュサーバーと通信する必要があります。

本番環境でのマイグレーションの強制実行

一部のマイグレーション操作は破壊的であり、データを失う可能性があります。本番データベースに対してこれらのコマンドを実行することを保護するために、コマンドの実行前に確認を求められます。確認なしでコマンドを強制実行するには、--forceフラグを使用します。

php artisan migrate --force

マイグレーションのロールバック

最新のマイグレーション操作をロールバックするには、rollback Artisanコマンドを使用できます。このコマンドは、最後の「バッチ」のマイグレーションをロールバックします。これには複数のマイグレーションファイルが含まれる場合があります。

php artisan migrate:rollback

rollbackコマンドにstepオプションを指定することで、限られた数のマイグレーションをロールバックできます。例えば、次のコマンドは最後の5つのマイグレーションをロールバックします。

php artisan migrate:rollback --step=5

rollbackコマンドにbatchオプションを指定することで、特定の「バッチ」のマイグレーションをロールバックできます。batchオプションは、アプリケーションのmigrationsデータベーステーブル内のバッチ値に対応します。例えば、次のコマンドはバッチ3のすべてのマイグレーションをロールバックします。

php artisan migrate:rollback --batch=3

マイグレーションが実行されるSQL文を実際に実行せずに確認したい場合は、migrate:rollbackコマンドに--pretendフラグを指定できます。

php artisan migrate:rollback --pretend

migrate:resetコマンドは、アプリケーションのすべてのマイグレーションをロールバックします。

php artisan migrate:reset

単一のコマンドでのロールバックとマイグレーション

migrate:refreshコマンドは、すべてのマイグレーションをロールバックし、migrateコマンドを実行します。このコマンドは、データベース全体を効果的に再作成します。

php artisan migrate:refresh

データベースをリフレッシュし、すべてのデータベースシードを実行する...

php artisan migrate:refresh --seed

`refresh`コマンドに`step`オプションを指定することで、限られた数のマイグレーションのみをロールバックして再マイグレーションすることができます。例えば、以下のコマンドは最後の5つのマイグレーションをロールバックして再マイグレーションします:

```shell
php artisan migrate:refresh --step=5

すべてのテーブルを削除してマイグレーションを実行

migrate:freshコマンドは、データベースからすべてのテーブルを削除し、その後migrateコマンドを実行します:

php artisan migrate:fresh

php artisan migrate:fresh --seed

デフォルトでは、migrate:freshコマンドはデフォルトのデータベース接続からテーブルを削除します。ただし、--databaseオプションを使用して、マイグレーションするデータベース接続を指定できます。データベース接続名は、アプリケーションのdatabase設定ファイルで定義された接続に対応する必要があります:

php artisan migrate:fresh --database=admin

Warning

migrate:freshコマンドは、プレフィックスに関係なくすべてのデータベーステーブルを削除します。このコマンドは、他のアプリケーションと共有されているデータベースで開発する際には注意して使用してください。

テーブル

テーブルの作成

新しいデータベーステーブルを作成するには、Schemaファサードのcreateメソッドを使用します。createメソッドは2つの引数を受け取ります:最初の引数はテーブルの名前で、2番目の引数は新しいテーブルを定義するために使用できるBlueprintオブジェクトを受け取るクロージャです:

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

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

テーブルを作成する際に、スキーマビルダーのカラムメソッドを使用してテーブルのカラムを定義できます。

テーブル/カラムの存在確認

hasTablehasColumnhasIndexメソッドを使用して、テーブル、カラム、またはインデックスの存在を確認できます:

if (Schema::hasTable('users')) {
    // "users" テーブルが存在する...
}

if (Schema::hasColumn('users', 'email')) {
    // "users" テーブルが存在し、"email" カラムを持つ...
}

if (Schema::hasIndex('users', ['email'], 'unique')) {
    // "users" テーブルが存在し、"email" カラムに一意のインデックスがある...
}

データベース接続とテーブルオプション

アプリケーションのデフォルト接続以外のデータベース接続でスキーマ操作を実行したい場合は、connectionメソッドを使用します:

Schema::connection('sqlite')->create('users', function (Blueprint $table) {
    $table->id();
});

さらに、テーブル作成の他の側面を定義するために、いくつかの他のプロパティとメソッドを使用できます。engineプロパティは、MariaDBまたはMySQLを使用する際にテーブルのストレージエンジンを指定するために使用できます:

Schema::create('users', function (Blueprint $table) {
    $table->engine('InnoDB');

    // ...
});

charsetcollationプロパティは、MariaDBまたはMySQLを使用する際に作成されるテーブルの文字セットと照合順序を指定するために使用できます:

Schema::create('users', function (Blueprint $table) {
    $table->charset('utf8mb4');
    $table->collation('utf8mb4_unicode_ci');

    // ...
});

temporaryメソッドは、テーブルが「一時的」であることを示すために使用できます。一時テーブルは現在の接続のデータベースセッションにのみ表示され、接続が閉じられると自動的に削除されます:

Schema::create('calculations', function (Blueprint $table) {
    $table->temporary();

    // ...
});

データベーステーブルに「コメント」を追加したい場合は、テーブルインスタンスのcommentメソッドを呼び出すことができます。テーブルコメントは現在、MariaDB、MySQL、およびPostgreSQLでのみサポートされています:

Schema::create('calculations', function (Blueprint $table) {
    $table->comment('Business calculations');

    // ...
});

テーブルの更新

Schemaファサードのtableメソッドは、既存のテーブルを更新するために使用できます。createメソッドと同様に、tableメソッドは2つの引数を受け取ります:テーブルの名前と、テーブルにカラムやインデックスを追加するために使用できるBlueprintインスタンスを受け取るクロージャです:

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

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

テーブルのリネーム/削除

既存のデータベーステーブルの名前を変更するには、renameメソッドを使用します:

use Illuminate\Support\Facades\Schema;

Schema::rename($from, $to);

既存のテーブルを削除するには、dropまたはdropIfExistsメソッドを使用できます:

Schema::drop('users');

Schema::dropIfExists('users');

外部キーを持つテーブルのリネーム

テーブルの名前を変更する前に、テーブル上の外部キー制約がマイグレーションファイル内で明示的な名前を持っていることを確認してください。そうでない場合、外部キー制約名は古いテーブル名を参照することになります。

カラム

カラムの作成

Schemaファサードのtableメソッドは、既存のテーブルを更新するために使用できます。createメソッドと同様に、tableメソッドは2つの引数を受け取ります:テーブルの名前と、テーブルにカラムを追加するために使用できるIlluminate\Database\Schema\Blueprintインスタンスを受け取るクロージャです:

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

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

利用可能なカラムタイプ

スキーマビルダーブループリントは、データベーステーブルに追加できるさまざまなタイプのカラムに対応するさまざまなメソッドを提供します。以下の表に、利用可能な各メソッドを示します:

bigIncrements()

bigIncrementsメソッドは、自動増分するUNSIGNED BIGINT(主キー)相当のカラムを作成します:

$table->bigIncrements('id');

bigInteger()

bigIntegerメソッドは、BIGINT相当のカラムを作成します:

$table->bigInteger('votes');

binary()

binaryメソッドは、BLOB相当のカラムを作成します:

$table->binary('photo');

MySQL、MariaDB、またはSQL Serverを使用する場合、lengthfixed引数を渡して、VARBINARYまたはBINARY相当のカラムを作成できます:

$table->binary('data', length: 16); // VARBINARY(16)

$table->binary('data', length: 16, fixed: true); // BINARY(16)

boolean()

booleanメソッドは、BOOLEAN相当のカラムを作成します。

$table->boolean('confirmed');

char()

charメソッドは、指定された長さのCHAR相当のカラムを作成します。

$table->char('name', length: 100);

dateTimeTz()

dateTimeTzメソッドは、オプションの小数秒精度を持つDATETIME(タイムゾーン付き)相当のカラムを作成します。

$table->dateTimeTz('created_at', precision: 0);

dateTime()

dateTimeメソッドは、オプションの小数秒精度を持つDATETIME相当のカラムを作成します。

$table->dateTime('created_at', precision: 0);

date()

dateメソッドは、DATE相当のカラムを作成します。

$table->date('created_at');

decimal()

decimalメソッドは、指定された精度(全体の桁数)とスケール(小数点以下の桁数)を持つDECIMAL相当のカラムを作成します。

$table->decimal('amount', total: 8, places: 2);

double()

doubleメソッドは、DOUBLE相当のカラムを作成します。

$table->double('amount');

enum()

enumメソッドは、指定された有効な値を持つENUM相当のカラムを作成します。

$table->enum('difficulty', ['easy', 'hard']);

float()

floatメソッドは、指定された精度を持つFLOAT相当のカラムを作成します。

$table->float('amount', precision: 53);

foreignId()

foreignIdメソッドは、UNSIGNED BIGINT相当のカラムを作成します。

$table->foreignId('user_id');

foreignIdFor()

foreignIdForメソッドは、指定されたモデルクラスに対して{column}_id相当のカラムを追加します。カラムの型は、モデルのキータイプに応じてUNSIGNED BIGINTCHAR(36)、またはCHAR(26)になります。

$table->foreignIdFor(User::class);

foreignUlid()

foreignUlidメソッドは、ULID相当のカラムを作成します。

$table->foreignUlid('user_id');

foreignUuid()

foreignUuidメソッドは、UUID相当のカラムを作成します。

$table->foreignUuid('user_id');

geography()

geographyメソッドは、指定された空間タイプとSRID(空間参照系識別子)を持つGEOGRAPHY相当のカラムを作成します。

$table->geography('coordinates', subtype: 'point', srid: 4326);

Note

空間タイプのサポートは、データベースドライバに依存します。詳細については、データベースのドキュメントを参照してください。アプリケーションがPostgreSQLデータベースを使用している場合、geographyメソッドを使用する前にPostGIS拡張機能をインストールする必要があります。

geometry()

geometryメソッドは、指定された空間タイプとSRID(空間参照系識別子)を持つGEOMETRY相当のカラムを作成します。

$table->geometry('positions', subtype: 'point', srid: 0);

Note

空間タイプのサポートは、データベースドライバに依存します。詳細については、データベースのドキュメントを参照してください。アプリケーションがPostgreSQLデータベースを使用している場合、geometryメソッドを使用する前にPostGIS拡張機能をインストールする必要があります。

id()

idメソッドは、bigIncrementsメソッドのエイリアスです。デフォルトでは、idカラムを作成しますが、カラムに別の名前を付けたい場合はカラム名を渡すことができます。

$table->id();

increments()

incrementsメソッドは、自動増分するUNSIGNED INTEGER相当のカラムを主キーとして作成します。

$table->increments('id');

integer()

integerメソッドは、INTEGER相当のカラムを作成します。

$table->integer('votes');

ipAddress()

ipAddressメソッドは、VARCHAR相当のカラムを作成します。

$table->ipAddress('visitor');

PostgreSQLを使用する場合、INETカラムが作成されます。

json()

jsonメソッドは、JSON相当のカラムを作成します。

$table->json('options');

jsonb()

jsonbメソッドは、JSONB相当のカラムを作成します。

$table->jsonb('options');

longText()

longTextメソッドは、LONGTEXT相当のカラムを作成します。

$table->longText('description');

MySQLまたはMariaDBを使用する場合、binary文字セットをカラムに適用してLONGBLOB相当のカラムを作成できます。

$table->longText('data')->charset('binary'); // LONGBLOB

macAddress()

macAddressメソッドは、MACアドレスを保持することを意図したカラムを作成します。PostgreSQLなどの一部のデータベースシステムには、このタイプのデータに対して専用のカラムタイプがあります。他のデータベースシステムでは、文字列相当のカラムが使用されます。

$table->macAddress('device');

mediumIncrements()

mediumIncrementsメソッドは、自動増分するUNSIGNED MEDIUMINT相当のカラムを主キーとして作成します。

$table->mediumIncrements('id');

mediumInteger()

mediumIntegerメソッドは、MEDIUMINT相当のカラムを作成します。

$table->mediumInteger('votes');

mediumText()

mediumTextメソッドは、MEDIUMTEXT相当のカラムを作成します。

$table->mediumText('description');

MySQLまたはMariaDBを使用する場合、binary文字セットをカラムに適用してMEDIUMBLOB相当のカラムを作成できます。

$table->mediumText('data')->charset('binary'); // MEDIUMBLOB

morphs()

morphsメソッドは、{column}_id相当のカラムと{column}_typeVARCHAR相当のカラムを追加する便利なメソッドです。{column}_idのカラムタイプは、モデルのキータイプに応じてUNSIGNED BIGINTCHAR(36)、またはCHAR(26)になります。

このメソッドは、ポリモーフィックなEloquentリレーションに必要なカラムを定義する際に使用されます。以下の例では、taggable_idtaggable_typeカラムが作成されます。

$table->morphs('taggable');

nullableTimestamps()

nullableTimestampsメソッドは、timestampsメソッドのエイリアスです。

$table->nullableTimestamps(precision: 0);

nullableMorphs()

このメソッドは、morphsメソッドと似ていますが、作成されるカラムは「nullable」になります。

$table->nullableMorphs('taggable');

nullableUlidMorphs()

このメソッドは、ulidMorphsメソッドと似ていますが、作成されるカラムは「nullable」になります。

$table->nullableUlidMorphs('taggable');

nullableUuidMorphs()

このメソッドは、uuidMorphsメソッドと似ていますが、作成されるカラムは「nullable」になります。

$table->nullableUuidMorphs('taggable');

rememberToken()

rememberTokenメソッドは、現在の「remember me」認証トークンを保存することを意図した、nullableのVARCHAR(100)相当のカラムを作成します。

$table->rememberToken();

set()

setメソッドは、指定された有効な値のリストを持つSET相当のカラムを作成します。

$table->set('flavors', ['strawberry', 'vanilla']);

smallIncrements()

smallIncrementsメソッドは、自動増分するUNSIGNED SMALLINT相当のカラムを主キーとして作成します。

$table->smallIncrements('id');

smallInteger()

smallIntegerメソッドは、SMALLINT相当のカラムを作成します。

$table->smallInteger('votes');

softDeletesTz()

softDeletesTzメソッドは、nullableのdeleted_atTIMESTAMP(タイムゾーン付き)相当のカラムを、オプションの小数秒精度で追加します。このカラムは、Eloquentの「ソフトデリート」機能に必要なdeleted_atタイムスタンプを保存することを意図しています。

$table->softDeletesTz('deleted_at', precision: 0);

softDeletes()

softDeletesメソッドは、nullableのdeleted_atTIMESTAMP相当のカラムを、オプションの小数秒精度で追加します。このカラムは、Eloquentの「ソフトデリート」機能に必要なdeleted_atタイムスタンプを保存することを意図しています。

$table->softDeletes('deleted_at', precision: 0);

string()

stringメソッドは、指定された長さのVARCHAR相当のカラムを作成します。

$table->string('name', length: 100);

text()

textメソッドは、TEXT相当のカラムを作成します。

$table->text('description');

MySQLまたはMariaDBを使用する場合、カラムにbinary文字セットを適用して、BLOB相当のカラムを作成できます。

$table->text('data')->charset('binary'); // BLOB

timeTz()

timeTzメソッドは、オプションの小数点以下の秒精度を持つTIME(タイムゾーン付き)相当のカラムを作成します。

$table->timeTz('sunrise', precision: 0);

time()

timeメソッドは、オプションの小数点以下の秒精度を持つTIME相当のカラムを作成します。

$table->time('sunrise', precision: 0);

timestampTz()

timestampTzメソッドは、オプションの小数点以下の秒精度を持つTIMESTAMP(タイムゾーン付き)相当のカラムを作成します。

$table->timestampTz('added_at', precision: 0);

timestamp()

timestampメソッドは、オプションの小数点以下の秒精度を持つTIMESTAMP相当のカラムを作成します。

$table->timestamp('added_at', precision: 0);

timestampsTz()

timestampsTzメソッドは、オプションの小数点以下の秒精度を持つcreated_atupdated_at TIMESTAMP(タイムゾーン付き)相当のカラムを作成します。

$table->timestampsTz(precision: 0);

timestamps()

timestampsメソッドは、オプションの小数点以下の秒精度を持つcreated_atupdated_at TIMESTAMP相当のカラムを作成します。

$table->timestamps(precision: 0);

tinyIncrements()

tinyIncrementsメソッドは、主キーとして自動インクリメントするUNSIGNED TINYINT相当のカラムを作成します。

$table->tinyIncrements('id');

tinyInteger()

tinyIntegerメソッドは、TINYINT相当のカラムを作成します。

$table->tinyInteger('votes');

tinyText()

tinyTextメソッドは、TINYTEXT相当のカラムを作成します。

$table->tinyText('notes');

MySQLまたはMariaDBを使用する場合、カラムにbinary文字セットを適用して、TINYBLOB相当のカラムを作成できます。

$table->tinyText('data')->charset('binary'); // TINYBLOB

unsignedBigInteger()

unsignedBigIntegerメソッドは、UNSIGNED BIGINT相当のカラムを作成します。

$table->unsignedBigInteger('votes');

unsignedInteger()

unsignedIntegerメソッドは、UNSIGNED INTEGER相当のカラムを作成します。

$table->unsignedInteger('votes');

unsignedMediumInteger()

unsignedMediumIntegerメソッドは、UNSIGNED MEDIUMINT相当のカラムを作成します。

$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

unsignedSmallIntegerメソッドは、UNSIGNED SMALLINT相当のカラムを作成します。

$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

unsignedTinyIntegerメソッドは、UNSIGNED TINYINT相当のカラムを作成します。

$table->unsignedTinyInteger('votes');

ulidMorphs()

ulidMorphsメソッドは、{column}_id CHAR(26)相当のカラムと{column}_type VARCHAR相当のカラムを追加する便利なメソッドです。

このメソッドは、ULID識別子を使用するポリモーフィックなEloquentリレーションに必要なカラムを定義するために使用されます。以下の例では、taggable_idtaggable_typeカラムが作成されます。

$table->ulidMorphs('taggable');

uuidMorphs()

uuidMorphsメソッドは、{column}_id CHAR(36)相当のカラムと{column}_type VARCHAR相当のカラムを追加する便利なメソッドです。

このメソッドは、UUID識別子を使用するポリモーフィックなEloquentリレーションに必要なカラムを定義するために使用されます。以下の例では、taggable_idtaggable_typeカラムが作成されます。

$table->uuidMorphs('taggable');

ulid()

ulidメソッドは、ULID相当のカラムを作成します。

$table->ulid('id');

uuid()

uuidメソッドは、UUID相当のカラムを作成します。

$table->uuid('id');

year()

yearメソッドは、YEAR相当のカラムを作成します。

$table->year('birth_year');

カラム修飾子

上記のカラムタイプに加えて、データベーステーブルにカラムを追加する際に使用できるいくつかのカラム「修飾子」があります。例えば、カラムを「NULL許容」にするには、nullableメソッドを使用できます。

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

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->nullable();
});

以下の表に、利用可能なすべてのカラム修飾子を示します。このリストには、インデックス修飾子は含まれていません。

修飾子 説明
->after('column') カラムを別のカラムの「後」に配置する(MariaDB / MySQL)。
->autoIncrement() INTEGERカラムを自動インクリメント(主キー)に設定する。
->charset('utf8mb4') カラムの文字セットを指定する(MariaDB / MySQL)。
->collation('utf8mb4_unicode_ci') カラムの照合順序を指定する。
->comment('my comment') カラムにコメントを追加する(MariaDB / MySQL / PostgreSQL)。
->default($value) カラムの「デフォルト」値を指定する。
->first() カラムをテーブルの「最初」に配置する(MariaDB / MySQL)。
->from($integer) 自動インクリメントフィールドの開始値を設定する(MariaDB / MySQL / PostgreSQL)。
->invisible() カラムをSELECT *クエリで「不可視」にする(MariaDB / MySQL)。
->nullable($value = true) カラムにNULL値を挿入できるようにする。
->storedAs($expression) 保存された生成カラムを作成する(MariaDB / MySQL / PostgreSQL / SQLite)。
->unsigned() INTEGERカラムをUNSIGNEDに設定する(MariaDB / MySQL)。
->useCurrent() TIMESTAMPカラムがCURRENT_TIMESTAMPをデフォルト値として使用するように設定する。
->useCurrentOnUpdate() TIMESTAMPカラムがレコードが更新されたときにCURRENT_TIMESTAMPを使用するように設定する(MariaDB / MySQL)。
->virtualAs($expression) 仮想生成カラムを作成する(MariaDB / MySQL / SQLite)。
->generatedAs($expression) 指定されたシーケンスオプションを持つIDカラムを作成する(PostgreSQL)。
->always() IDカラムのシーケンス値と入力の優先順位を定義する(PostgreSQL)。

デフォルト式

default修飾子は、値またはIlluminate\Database\Query\Expressionインスタンスを受け入れます。Expressionインスタンスを使用すると、Laravelが値を引用符で囲むのを防ぎ、データベース固有の関数を使用できるようになります。これは、特にJSONカラムにデフォルト値を割り当てる必要がある場合に特に便利です。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
    /**
     * マイグレーションを実行する。
     */
    public function up(): void
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }
};

Warning

デフォルト式のサポートは、データベースドライバ、データベースのバージョン、およびフィールドタイプに依存します。データベースのドキュメントを参照してください。

カラムの順序

MariaDBまたはMySQLデータベースを使用する場合、スキーマ内の既存のカラムの後にカラムを追加するためにafterメソッドを使用できます。

$table->after('password', function (Blueprint $table) {
    $table->string('address_line1');
    $table->string('address_line2');
    $table->string('city');
});

カラムの変更

changeメソッドを使用すると、既存のカラムのタイプと属性を変更できます。例えば、stringカラムのサイズを増やしたい場合があります。changeメソッドを実際に見るために、nameカラムのサイズを25から50に増やしてみましょう。これを行うには、カラムの新しい状態を定義してからchangeメソッドを呼び出します。

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

カラムを変更する際には、カラム定義に保持したいすべての修飾子を明示的に含める必要があります。欠落している属性は削除されます。例えば、unsigneddefault、およびcomment属性を保持するには、カラムを変更する際に各修飾子を明示的に呼び出す必要があります。

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});

changeメソッドはカラムのインデックスを変更しません。したがって、カラムを変更する際にインデックス修飾子を使用して明示的にインデックスを追加または削除することができます。

// インデックスを追加...
$table->bigIncrements('id')->primary()->change();

// インデックスを削除...
$table->char('postal_code', 10)->unique(false)->change();

カラムの名前変更

カラムの名前を変更するには、スキーマビルダーが提供するrenameColumnメソッドを使用できます。

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});

カラムの削除

カラムを削除するには、スキーマビルダーのdropColumnメソッドを使用できます。

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

dropColumnメソッドにカラム名の配列を渡すことで、テーブルから複数のカラムを削除できます。

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});

利用可能なコマンドエイリアス

Laravelは、一般的なタイプのカラムを削除するための便利なメソッドをいくつか提供しています。以下の表に各メソッドが記載されています。

コマンド 説明
$table->dropMorphs('morphable'); morphable_idmorphable_typeカラムを削除。
$table->dropRememberToken(); remember_tokenカラムを削除。
$table->dropSoftDeletes(); deleted_atカラムを削除。
$table->dropSoftDeletesTz(); dropSoftDeletes()メソッドのエイリアス。
$table->dropTimestamps(); created_atupdated_atカラムを削除。
$table->dropTimestampsTz(); dropTimestamps()メソッドのエイリアス。

インデックス

インデックスの作成

Laravelのスキーマビルダーは、いくつかのタイプのインデックスをサポートしています。以下の例では、新しいemailカラムを作成し、その値が一意であることを指定しています。インデックスを作成するために、カラム定義にuniqueメソッドをチェーンできます。

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

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->unique();
});

または、カラムを定義した後にインデックスを作成することもできます。そのためには、スキーマビルダーブループリントのuniqueメソッドを呼び出す必要があります。このメソッドは、一意のインデックスを受け取るカラムの名前を受け取ります。

$table->unique('email');

インデックスメソッドにカラムの配列を渡すことで、複合(または複合)インデックスを作成できます。

$table->index(['account_id', 'created_at']);

インデックスを作成する際、Laravelは自動的にテーブル名、カラム名、およびインデックスタイプに基づいてインデックス名を生成しますが、メソッドの2番目の引数を渡してインデックス名を自分で指定することもできます。

$table->unique('email', 'unique_email');

利用可能なインデックスタイプ

Laravelのスキーマビルダーブループリントクラスは、Laravelがサポートする各タイプのインデックスを作成するためのメソッドを提供しています。各インデックスメソッドは、インデックスの名前を指定するためのオプションの2番目の引数を受け取ります。省略した場合、名前はテーブル名、カラム名、およびインデックスタイプから派生します。以下の表に、利用可能な各インデックスメソッドが記載されています。

コマンド 説明
$table->primary('id'); 主キーを追加。
$table->primary(['id', 'parent_id']); 複合キーを追加。
$table->unique('email'); 一意のインデックスを追加。
$table->index('state'); インデックスを追加。
$table->fullText('body'); 全文インデックスを追加(MariaDB / MySQL / PostgreSQL)。
$table->fullText('body')->language('english'); 指定された言語の全文インデックスを追加(PostgreSQL)。
$table->spatialIndex('location'); 空間インデックスを追加(SQLite以外)。

インデックスの名前変更

インデックスの名前を変更するには、スキーマビルダーブループリントが提供するrenameIndexメソッドを使用できます。このメソッドは、現在のインデックス名を最初の引数として、希望する名前を2番目の引数として受け取ります。

$table->renameIndex('from', 'to')

インデックスの削除

インデックスを削除するには、インデックスの名前を指定する必要があります。デフォルトでは、Laravelは自動的にテーブル名、インデックスされたカラムの名前、およびインデックスタイプに基づいてインデックス名を割り当てます。以下にいくつかの例を示します。

コマンド 説明
$table->dropPrimary('users_id_primary'); "users"テーブルから主キーを削除。
$table->dropUnique('users_email_unique'); "users"テーブルから一意のインデックスを削除。
$table->dropIndex('geo_state_index'); "geo"テーブルから基本インデックスを削除。
$table->dropFullText('posts_body_fulltext'); "posts"テーブルから全文インデックスを削除。
$table->dropSpatialIndex('geo_location_spatialindex'); "geo"テーブルから空間インデックスを削除(SQLite以外)。

インデックスを削除するメソッドにカラムの配列を渡すと、テーブル名、カラム、およびインデックスタイプに基づいて従来のインデックス名が生成されます。

Schema::table('geo', function (Blueprint $table) {
    $table->dropIndex(['state']); // 'geo_state_index'インデックスを削除
});

外部キー制約

Laravelは、データベースレベルで参照整合性を強制するために使用される外部キー制約の作成もサポートしています。例えば、postsテーブルにuser_idカラムを定義し、usersテーブルのidカラムを参照します。

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

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');

    $table->foreign('user_id')->references('id')->on('users');
});

この構文はかなり冗長であるため、Laravelは規約を使用して開発者エクスペリエンスを向上させる追加の簡潔なメソッドを提供しています。foreignIdメソッドを使用してカラムを作成する場合、上記の例は次のように書き換えることができます。

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained();
});

foreignIdメソッドはUNSIGNED BIGINT相当のカラムを作成し、constrainedメソッドは規約を使用して参照されるテーブルとカラムを決定します。テーブル名がLaravelの規約に一致しない場合は、constrainedメソッドに手動で指定することができます。さらに、生成されるインデックスに割り当てるべき名前を指定することもできます。

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained(
        table: 'users', indexName: 'posts_user_id'
    );
});

"on delete" および "on update" プロパティの制約に対して、希望するアクションを指定することもできます:

$table->foreignId('user_id')
      ->constrained()
      ->onUpdate('cascade')
      ->onDelete('cascade');

これらのアクションに対して、代替的で表現力豊かな構文も提供されています:

メソッド 説明
$table->cascadeOnUpdate(); 更新時にカスケードする。
$table->restrictOnUpdate(); 更新時に制限する。
$table->noActionOnUpdate(); 更新時に何もしない。
$table->cascadeOnDelete(); 削除時にカスケードする。
$table->restrictOnDelete(); 削除時に制限する。
$table->nullOnDelete(); 削除時に外部キーの値をnullに設定する。

追加のカラム修飾子は、constrainedメソッドの前に呼び出す必要があります:

$table->foreignId('user_id')
      ->nullable()
      ->constrained();

外部キーの削除

外部キーを削除するには、dropForeignメソッドを使用し、削除する外部キー制約の名前を引数として渡します。外部キー制約はインデックスと同じ命名規則を使用します。つまり、外部キー制約名はテーブル名と制約内のカラム名に基づき、その後に "_foreign" サフィックスが付きます:

$table->dropForeign('posts_user_id_foreign');

または、外部キーを保持するカラム名を含む配列をdropForeignメソッドに渡すこともできます。配列はLaravelの制約命名規則を使用して外部キー制約名に変換されます:

$table->dropForeign(['user_id']);

外部キー制約の切り替え

マイグレーション内で外部キー制約を有効または無効にするには、以下のメソッドを使用します:

Schema::enableForeignKeyConstraints();

Schema::disableForeignKeyConstraints();

Schema::withoutForeignKeyConstraints(function () {
    // このクロージャ内では制約が無効になります...
});

Warning

SQLiteはデフォルトで外部キー制約を無効にしています。SQLiteを使用する場合、マイグレーションで外部キーを作成しようとする前に、データベース設定で外部キーのサポートを有効にするようにしてください。

イベント

便宜上、各マイグレーション操作はイベントを発行します。以下のすべてのイベントは、基本クラスIlluminate\Database\Events\MigrationEventを拡張しています:

クラス 説明
Illuminate\Database\Events\MigrationsStarted マイグレーションのバッチが実行されようとしています。
Illuminate\Database\Events\MigrationsEnded マイグレーションのバッチが実行を終了しました。
Illuminate\Database\Events\MigrationStarted 単一のマイグレーションが実行されようとしています。
Illuminate\Database\Events\MigrationEnded 単一のマイグレーションが実行を終了しました。
Illuminate\Database\Events\NoPendingMigrations マイグレーションコマンドが保留中のマイグレーションを見つけませんでした。
Illuminate\Database\Events\SchemaDumped データベーススキーマのダンプが完了しました。
Illuminate\Database\Events\SchemaLoaded 既存のデータベーススキーマのダンプが読み込まれました。

ユーザーノート