データベース: マイグレーション
はじめに
マイグレーションはデータベースのバージョン管理のようなもので、チームメンバーがアプリケーションのデータベーススキーマ定義を定義して共有できます。ソース管理から変更内容を取り込んだ後、チームメンバーに手動でローカルデータベーススキーマにカラムを追加するように伝えたことがある場合、データベースマイグレーションが解決する問題に直面しています。
Laravel の Schema
ファサード は、Laravel がサポートするすべてのデータベースシステムでテーブルを作成および操作するためのデータベースに依存しないサポートを提供します。通常、マイグレーションはファサードを使用してデータベースのテーブルとカラムを作成して変更します。
マイグレーションの生成
make:migration
Artisan コマンド を使用して、データベースマイグレーションを生成できます。新しいマイグレーションは database/migrations
ディレクトリに配置されます。各マイグレーションファイル名にはタイムスタンプが含まれており、Laravel はマイグレーションの順序を判断できます
php artisan make:migration create_flights_table
Laravel は、マイグレーション名のテーブル名と、マイグレーションが新しいテーブルを作成するかどうかを推測するために、マイグレーション名を使用します。Laravel がマイグレーション名からテーブル名を確認できる場合、Laravel は生成されたマイグレーションファイルを指定されたテーブルで事前に埋めます。それ以外の場合、マイグレーションファイルでテーブルを手動で指定するだけです。
生成されたマイグレーションのカスタムパスを指定したい場合は、make:migration
コマンドを実行するときに --path
オプションを使用できます。指定されたパスは、アプリケーションの基本パスを基準にする必要があります。
マイグレーションスタブは、スタブパブリッシング を使用してカスタマイズできます。
マイグレーションのスキュー
アプリケーションを構築するにつれて、時間が経つにつれてマイグレーションが増加することがあります。これは、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:dumpphp artisan schema:dump --database=testing --prune
データベースの schema ファイルは他のチームの新規開発者がアプリケーションの初期データベース構造を素早く作成できるようにソース制御にコミットする必要があります。
マイグレーションの統合処理は MariaDB、MySQL、PostgreSQL、SQLite データベースでのみ利用でき、データベースのコマンドラインクライアントを使用します。
マイグレーションの構造
マイグレーションクラスには up
と down
という 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
この機能を使用するには、アプリケーションでアプリケーションの既定のキャッシュドライバーとして memcached
、redis
、dynamodb
、database
、file
、または 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
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();});
テーブルを作成するときは、スキーマビルダーの 列メソッド を使用して、テーブルの列を定義できます。
テーブル/列の存在を判断する
hasTable
、hasColumn
、hasIndex
メソッドを使用して、テーブル、列、またはインデックスの存在を調べることができます
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'); // ...});
charset
と collation
プロパティは、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 bigInteger binary boolean char dateTimeTz dateTime date decimal double enum float foreignId foreignIdFor foreignUlid foreignUuid geography geometry id increments integer ipAddress json jsonb longText macAddress mediumIncrements mediumInteger mediumText morphs nullableMorphs nullableTimestamps nullableUlidMorphs nullableUuidMorphs rememberToken set smallIncrements smallInteger softDeletesTz softDeletes string text timeTz time timestampTz timestamp timestampsTz timestamps tinyIncrements tinyInteger tinyText unsignedBigInteger unsignedInteger unsignedMediumInteger unsignedSmallInteger unsignedTinyInteger ulidMorphs uuidMorphs ulid uuid vector year
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 BIGINT
、CHAR(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);
空間タイプのサポートはデータベースドライバに依存します。データベースのドキュメントを参照してください。アプリケーションで PostgreSQL データベースを使用している場合、 geography
メソッドを使用する前に PostGIS 拡張機能をインストールする必要があります。
geometry()
geometry
メソッドは指定された空間タイプと SRID (空間参照システム ID) を持つ GEOMETRY
互換列を作成します
$table->geometry('positions', subtype: 'point', srid: 0);
空間タイプのサポートはデータベースドライバに依存します。データベースのドキュメントを参照してください。アプリケーションで 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 BIGINT
、CHAR(36)
、または CHAR(26)
のいずれかになります。
このメソッドは、多相 Eloquent リレーションシップ に必要な列を定義する場合に使用することを目的としています。次の例では、 taggable_id
と taggable_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(); }); }};
デフォルト式のサポートは、データベースドライバー、データベースのバージョン、およびフィールドのタイプによって異なります。データベースのドキュメントを参照してください。
列の順序
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();});
列を変更する場合、列定義に保持するすべての修飾子を明示的に含める必要があります。欠落している属性は削除されます。たとえば、unsigned
、default
、および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_id とmorphable_type 列を削除します。 |
$table->dropRememberToken(); |
remember_token 列を削除します。 |
$table->dropSoftDeletes(); |
deleted_at 列を削除します。 |
$table->dropSoftDeletesTz(); |
dropSoftDeletes() メソッドのエイリアスです。 |
$table->dropTimestamps(); |
created_at とupdated_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...});
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 |
既存のデータベース スキーマ ダンプが読み込まれました。 |