コンテンツへスキップ

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

イントロダクション

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

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

マイグレーションの生成

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

1php artisan make:migration create_flights_table

Laravelはマイグレーションの名前を使って、テーブルの名前と、マイグレーションが新しいテーブルを作成するかどうかを推測しようとします。Laravelがマイグレーション名からテーブル名を判断できた場合、Laravelは生成されたマイグレーションファイルに指定されたテーブルをあらかじめ記述します。そうでなければ、マイグレーションファイルでテーブルを手動で指定するだけです。

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

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

マイグレーションのスカッシュ

アプリケーションを構築していくと、時間の経過とともにより多くのマイグレーションが蓄積される可能性があります。これにより、database/migrationsディレクトリが何百ものマイグレーションで肥大化する可能性があります。必要であれば、マイグレーションを単一のSQLファイルに「スカッシュ(squash)」できます。開始するには、schema:dumpコマンドを実行します。

1php artisan schema:dump
2 
3# Dump the current database schema and prune all existing migrations...
4php artisan schema:dump --prune

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

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

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

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

マイグレーションのスカッシュはMariaDB、MySQL、PostgreSQL、SQLiteデータベースでのみ利用可能で、データベースのコマンドラインクライアントを利用します。

マイグレーションの構造

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

これらの両方のメソッド内で、Laravelスキーマビルダを使用して、テーブルを記述的に作成および変更できます。Schemaビルダで利用可能なすべてのメソッドについては、そのドキュメントをチェックしてください。たとえば、以下のマイグレーションはflightsテーブルを作成します。

1<?php
2 
3use Illuminate\Database\Migrations\Migration;
4use Illuminate\Database\Schema\Blueprint;
5use Illuminate\Support\Facades\Schema;
6 
7return new class extends Migration
8{
9 /**
10 * Run the migrations.
11 */
12 public function up(): void
13 {
14 Schema::create('flights', function (Blueprint $table) {
15 $table->id();
16 $table->string('name');
17 $table->string('airline');
18 $table->timestamps();
19 });
20 }
21 
22 /**
23 * Reverse the migrations.
24 */
25 public function down(): void
26 {
27 Schema::drop('flights');
28 }
29};

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

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

1/**
2 * The database connection that should be used by the migration.
3 *
4 * @var string
5 */
6protected $connection = 'pgsql';
7 
8/**
9 * Run the migrations.
10 */
11public function up(): void
12{
13 // ...
14}

マイグレーションの実行

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

1php artisan migrate

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

1php artisan migrate:status

実際にマイグレーションを実行せずに、マイグレーションによって実行されるSQLステートメントを確認したい場合は、migrateコマンドに--pretendフラグを指定します。

1php artisan migrate --pretend

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

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

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

1php artisan migrate --isolated

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

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

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

1php artisan migrate --force

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

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

1php artisan migrate:rollback

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

1php artisan migrate:rollback --step=5

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

1php artisan migrate:rollback --batch=3

実際にマイグレーションを実行せずに、マイグレーションによって実行されるSQLステートメントを確認したい場合は、migrate:rollbackコマンドに--pretendフラグを指定します。

1php artisan migrate:rollback --pretend

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

1php artisan migrate:reset

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

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

1php artisan migrate:refresh
2 
3# Refresh the database and run all database seeds...
4php artisan migrate:refresh --seed

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

1php artisan migrate:refresh --step=5

全テーブルの削除とマイグレート

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

1php artisan migrate:fresh
2 
3php artisan migrate:fresh --seed

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

1php artisan migrate:fresh --database=admin

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

テーブル

テーブルの作成

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

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::create('users', function (Blueprint $table) {
5 $table->id();
6 $table->string('name');
7 $table->string('email');
8 $table->timestamps();
9});

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

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

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

1if (Schema::hasTable('users')) {
2 // The "users" table exists...
3}
4 
5if (Schema::hasColumn('users', 'email')) {
6 // The "users" table exists and has an "email" column...
7}
8 
9if (Schema::hasIndex('users', ['email'], 'unique')) {
10 // The "users" table exists and has a unique index on the "email" column...
11}

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

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

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

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

1Schema::create('users', function (Blueprint $table) {
2 $table->engine('InnoDB');
3 
4 // ...
5});

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

1Schema::create('users', function (Blueprint $table) {
2 $table->charset('utf8mb4');
3 $table->collation('utf8mb4_unicode_ci');
4 
5 // ...
6});

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

1Schema::create('calculations', function (Blueprint $table) {
2 $table->temporary();
3 
4 // ...
5});

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

1Schema::create('calculations', function (Blueprint $table) {
2 $table->comment('Business calculations');
3 
4 // ...
5});

テーブルの更新

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

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::table('users', function (Blueprint $table) {
5 $table->integer('votes');
6});

テーブルの名前変更/削除

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

1use Illuminate\Support\Facades\Schema;
2 
3Schema::rename($from, $to);

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

1Schema::drop('users');
2 
3Schema::dropIfExists('users');

外部キーを持つテーブルの名前変更

テーブルの名前を変更する前に、テーブル上の外部キー制約が、Laravelに規約に基づいた名前を割り当てさせるのではなく、マイグレーションファイルで明示的な名前を持っていることを確認する必要があります。そうしないと、外部キー制約名は古いテーブル名を参照してしまいます。

カラム

カラムの作成

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

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::table('users', function (Blueprint $table) {
5 $table->integer('votes');
6});

利用可能なカラムタイプ

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

論理値型

文字列&テキスト型

数値型

日付&時刻型

バイナリ型

オブジェクト&JSON型

UUID&ULID型

空間データ型

リレーションシップ型

特殊型

bigIncrements()

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

1$table->bigIncrements('id');

bigInteger()

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

1$table->bigInteger('votes');

binary()

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

1$table->binary('photo');

MySQL、MariaDB、またはSQL Serverを利用する場合、VARBINARYまたはBINARY相当のカラムを作成するためにlengthfixed引数を渡すことができます。

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

boolean()

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

1$table->boolean('confirmed');

char()

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

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

dateTimeTz()

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

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

dateTime()

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

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

date()

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

1$table->date('created_at');

decimal()

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

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

double()

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

1$table->double('amount');

enum()

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

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

float()

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

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

foreignId()

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

1$table->foreignId('user_id');

foreignIdFor()

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

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

foreignUlid()

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

1$table->foreignUlid('user_id');

foreignUuid()

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

1$table->foreignUuid('user_id');

geography()

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

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

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

geometry()

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

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

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

id()

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

1$table->id();

increments()

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

1$table->increments('id');

integer()

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

1$table->integer('votes');

ipAddress()

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

1$table->ipAddress('visitor');

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

json()

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

1$table->json('options');

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

jsonb()

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

1$table->jsonb('options');

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

longText()

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

1$table->longText('description');

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

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

macAddress()

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

1$table->macAddress('device');

mediumIncrements()

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

1$table->mediumIncrements('id');

mediumInteger()

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

1$table->mediumInteger('votes');

mediumText()

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

1$table->mediumText('description');

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

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

morphs()

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

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

1$table->morphs('taggable');

nullableMorphs()

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

1$table->nullableMorphs('taggable');

nullableUlidMorphs()

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

1$table->nullableUlidMorphs('taggable');

nullableUuidMorphs()

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

1$table->nullableUuidMorphs('taggable');

rememberToken()

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

1$table->rememberToken();

set()

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

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

smallIncrements()

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

1$table->smallIncrements('id');

smallInteger()

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

1$table->smallInteger('votes');

softDeletesTz()

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

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

softDeletes()

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

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

string()

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

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

text()

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

1$table->text('description');

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

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

timeTz()

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

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

time()

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

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

timestampTz()

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

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

timestamp()

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

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

timestampsTz()

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

1$table->timestampsTz(precision: 0);

timestamps()

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

1$table->timestamps(precision: 0);

tinyIncrements()

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

1$table->tinyIncrements('id');

tinyInteger()

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

1$table->tinyInteger('votes');

tinyText()

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

1$table->tinyText('notes');

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

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

unsignedBigInteger()

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

1$table->unsignedBigInteger('votes');

unsignedInteger()

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

1$table->unsignedInteger('votes');

unsignedMediumInteger()

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

1$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

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

1$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

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

1$table->unsignedTinyInteger('votes');

ulidMorphs()

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

このメソッドは、ULID識別子を使用するポリモーフィックなEloquentリレーションシップに必要なカラムを定義する際に使用することを目的としています。次の例では、taggable_idtaggable_typeカラムが作成されます。

1$table->ulidMorphs('taggable');

uuidMorphs()

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

このメソッドは、UUID識別子を使用するポリモーフィックなEloquentリレーションシップに必要なカラムを定義する際に使用することを目的としています。次の例では、taggable_idtaggable_typeカラムが作成されます。

1$table->uuidMorphs('taggable');

ulid()

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

1$table->ulid('id');

uuid()

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

1$table->uuid('id');

vector()

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

1$table->vector('embedding', dimensions: 100);

year()

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

1$table->year('birth_year');

カラム修飾子

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

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::table('users', function (Blueprint $table) {
5 $table->string('email')->nullable();
6});

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

修飾子 説明
->after('column') カラムを別のカラムの「後(after)」に配置します(MariaDB / MySQL)。
->autoIncrement() INTEGERカラムを自動増分(主キー)として設定します。
->charset('utf8mb4') カラムの文字セットを指定します(MariaDB / MySQL)。
->collation('utf8mb4_unicode_ci') カラムの照合順序を指定します。
->comment('my comment') カラムにコメントを追加します(MariaDB / MySQL / PostgreSQL)。
->default($value) カラムの「デフォルト(default)」値を指定します。
->first() カラムをテーブルの「最初(first)」に配置します(MariaDB / MySQL)。
->from($integer) 自動増分フィールドの開始値を設定します(MariaDB / MySQL / PostgreSQL)。
->invisible() カラムをSELECT *クエリに対して「非表示(invisible)」にします(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が値を引用符で囲むのを防ぎ、データベース固有の関数を使用できます。これが特に役立つ状況の1つは、JSONカラムにデフォルト値を割り当てる必要がある場合です。

1<?php
2 
3use Illuminate\Support\Facades\Schema;
4use Illuminate\Database\Schema\Blueprint;
5use Illuminate\Database\Query\Expression;
6use Illuminate\Database\Migrations\Migration;
7 
8return new class extends Migration
9{
10 /**
11 * Run the migrations.
12 */
13 public function up(): void
14 {
15 Schema::create('flights', function (Blueprint $table) {
16 $table->id();
17 $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
18 $table->timestamps();
19 });
20 }
21};

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

カラムの順序

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

1$table->after('password', function (Blueprint $table) {
2 $table->string('address_line1');
3 $table->string('address_line2');
4 $table->string('city');
5});

カラムの変更

changeメソッドを使用すると、既存のカラムの型と属性を変更できます。たとえば、stringカラムのサイズを大きくしたい場合などです。changeメソッドの動作を確認するために、nameカラムのサイズを25から50に増やしてみましょう。これを達成するには、カラムの新しい状態を定義し、changeメソッドを呼び出すだけです。

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

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

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

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

1// Add an index...
2$table->bigIncrements('id')->primary()->change();
3 
4// Drop an index...
5$table->char('postal_code', 10)->unique(false)->change();

カラム名の変更

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

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

カラムの削除

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

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

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

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

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

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メソッドをチェーンします。

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::table('users', function (Blueprint $table) {
5 $table->string('email')->unique();
6});

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

1$table->unique('email');

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

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

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

1$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番目の引数として受け入れます。

1$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を除く)。

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

1Schema::table('geo', function (Blueprint $table) {
2 $table->dropIndex(['state']); // Drops index 'geo_state_index'
3});

外部キー制約

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

1use Illuminate\Database\Schema\Blueprint;
2use Illuminate\Support\Facades\Schema;
3 
4Schema::table('posts', function (Blueprint $table) {
5 $table->unsignedBigInteger('user_id');
6 
7 $table->foreign('user_id')->references('id')->on('users');
8});

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

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

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

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

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

1$table->foreignId('user_id')
2 ->constrained()
3 ->onUpdate('cascade')
4 ->onDelete('cascade');

これらのアクションには、代替の、より表現力豊かな構文も提供されています。

メソッド 説明
$table->cascadeOnUpdate(); 更新はカスケードされるべきです。
$table->restrictOnUpdate(); 更新は制限されるべきです。
$table->nullOnUpdate(); 更新は外部キーの値をnullに設定するべきです。
$table->noActionOnUpdate(); 更新時にアクションなし。
$table->cascadeOnDelete(); 削除はカスケードされるべきです。
$table->restrictOnDelete(); 削除は制限されるべきです。
$table->nullOnDelete(); 削除は外部キーの値をnullに設定するべきです。
$table->noActionOnDelete(); 子レコードが存在する場合、削除を防ぎます。

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

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

外部キーの削除

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

1$table->dropForeign('posts_user_id_foreign');

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

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

外部キー制約の切り替え

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

1Schema::enableForeignKeyConstraints();
2 
3Schema::disableForeignKeyConstraints();
4 
5Schema::withoutForeignKeyConstraints(function () {
6 // Constraints disabled within this closure...
7});

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 既存のデータベーススキーマダンプがロードされました。

Laravelは最も生産的な方法です
ソフトウェアを構築、デプロイ、監視します。