コンテンツにスキップ

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

はじめに

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

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

マイグレーションの生成

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

php artisan make:migration create_flights_table

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

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

lightbulb

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

マイグレーションのスキュー

アプリケーションを構築するにつれて、時間が経つにつれてマイグレーションが増加することがあります。これは、database/migrations ディレクトリが何百ものマイグレーションで膨張する可能性があることを意味します。必要に応じて、マイグレーションを 1 つの SQL ファイルに「スキュー」できます。まず schema:dump コマンドを実行します

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

このコマンドを実行すると、Laravel はアプリケーションの database/schema ディレクトリに "schema" ファイルを書き込みます。この schema ファイルの名前は、データベースの接続に対応します。この状態でデータベースのマイグレーションを試み、他のマイグレーションが実行されていなければ、まず使用しているデータベース接続の schema ファイル内の SQL ステートメントが実行されます。schema ファイルの SQL ステートメントを実行してから、schema ダンプに含まれない残りのマイグレーションが実行されます。

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

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

データベースの schema ファイルは他のチームの新規開発者がアプリケーションの初期データベース構造を素早く作成できるようにソース制御にコミットする必要があります。

exclamation

マイグレーションの統合処理は MariaDB、MySQL、PostgreSQL、SQLite データベースでのみ利用でき、データベースのコマンドラインクライアントを使用します。

マイグレーションの構造

マイグレーションクラスには updown という 2 つのメソッドがあります。up メソッドは新しいテーブル、列、またはインデックスをデータベースに追加するために使用し、down メソッドは up が実行した操作を取り消します。

これらのメソッドのどちらでも、Laravel の schema ビルダーを使用して表現力豊かな方法でテーブルを作成および変更できます。Schema ビルダーで使用できるすべてのメソッドについては、ドキュメント で確認できます。たとえば、次のマイグレーションは flights テーブルを作成します。

<?php
 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
 
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::drop('flights');
}
};

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

アプリケーションの既定のデータベース接続以外のデータベース接続とマイグレーションがやり取りする場合は、マイグレーションの $connection プロパティを設定する必要があります

/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'pgsql';
 
/**
* Run the migrations.
*/
public function up(): void
{
// ...
}

マイグレーションの実行

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

php artisan migrate

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

php artisan migrate:status

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

php artisan migrate --pretend

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

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

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

php artisan migrate --isolated
exclamation

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

実稼働環境でマイグレーションを実行するには

一部のマイグレーション操作は破壊的であり、データが失われる可能性があります。こうしたコマンドが実稼働データベースに対して実行されないように、コマンドの実行前に確認メッセージが表示されます。確認メッセージを表示せずにコマンドを実行するには、--force フラグを使用します。

php artisan migrate --force

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

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

php artisan migrate:rollback

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

php artisan migrate:rollback --step=5

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

php artisan migrate:rollback --batch=3

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

php artisan migrate:rollback --pretend

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

php artisan migrate:reset

1 つのコマンドを使用してロールバックおよびマイグレーションする

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

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

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

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
exclamation

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')) {
// The "users" table exists...
}
 
if (Schema::hasColumn('users', 'email')) {
// The "users" table exists and has an "email" column...
}
 
if (Schema::hasIndex('users', ['email'], 'unique')) {
// The "users" table exists and has a unique index on the "email" column...
}

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

アプリケーションのデフォルト接続でないデータベース接続でスキーマ操作を実行する場合は、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');

外部キーのあるテーブルの名前変更

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

カラム

カラムの作成

schemaファサードのtableメソッドは、既存のテーブルを更新するために使用できます。createメソッドと同様に、tableメソッドは2つの引数を受け取ります。1つはテーブルの名前、もう1つはテーブルに列を追加するために使用できる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を使用する場合、length引数とfixed引数を渡して、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 (空間参照システム ID) を持つ GEOGRAPHY 互換列を作成します

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

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

geometry()

geometry メソッドは指定された空間タイプと SRID (空間参照システム ID) を持つ GEOMETRY 互換列を作成します

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

空間タイプのサポートはデータベースドライバに依存します。データベースのドキュメントを参照してください。アプリケーションで 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 を使用する場合、 LONGBLOB 互換列を作成するために、列に binary 文字セットを適用できます

$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 を使用する場合、 MEDIUMBLOB 互換列を作成するために、列に binary 文字セットを適用できます

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

morphs()

morphs メソッドは {column}_id 互換列と {column}_type VARCHAR 互換列を追加する便利なメソッドです。{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 メソッドは、現在の「ログイン状態を記憶する」認証トークンを格納する意図のある 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_at TIMESTAMP(タイムゾーン付き)対応のカラムを追加します。このカラムは、Eloquentの「ソフト削除」機能に必要な deleted_at タイムスタンプを格納する意図があります

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

softDeletes()

softDeletes メソッドは、オプションで小数秒の精度を持つ nullable の deleted_at TIMESTAMP 対応のカラムを追加します。このカラムは、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を使用している場合、BLOB対応のカラムを作成するために컬ムにbinaryの文字セットを適用することができます

$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_at および updated_at TIMESTAMP(タイムゾーン付き)対応のカラムを作成します

$table->timestampsTz(precision: 0);

timestamps()

timestamps メソッドは、オプションで小数秒の精度を持つ created_at および updated_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を使用している場合、TINYBLOB対応のカラムを作成するために컬ムにbinaryの文字セットを適用することができます

$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_id および taggable_type のカラムが作成されます

$table->ulidMorphs('taggable');

uuidMorphs()

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

このメソッドは UUID 識別子を使用する多相Eloquent リレーションシップに必要なカラムを定義する場合に使用するためのものと意図されています。次の例では、taggable_id および taggable_type のカラムが作成されます

$table->uuidMorphs('taggable');

ulid()

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

$table->ulid('id');

uuid()

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

$table->uuid('id');

vector()

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

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

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 が値を引用符で囲むことを防ぎ、データベース固有の関数を使用できるようになります。特にこれが役に立つ状況の 1 つに、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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->json('movies')->default(new Expression('(JSON_ARRAY())'));
$table->timestamps();
});
}
};
exclamation

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

列の順序

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メソッドは、列のインデックスを変更しません。したがって、列を変更するときにインデックス修飾子を使用して、明示的にインデックスを追加または削除できます。

// Add an index...
$table->bigIncrements('id')->primary()->change();
 
// Drop an index...
$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');` (SQLiteを除き)"geo"テーブルから空間インデックスを削除します。

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

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

外部キー制約

Laravelは、データベースレベルで参照整合性を強制するために使用される外部キー制約を作成するためサポートを提供します。たとえば、`posts`テーブルに`users`テーブルの`id`カラムを参照する`user_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'
);
});

制約の"削除時"と"更新時"のプロパティに必要なアクションを指定することもできます。

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

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

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

その他のカラム修飾子は`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 () {
// Constraints disabled within this closure...
});
exclamation

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