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

イントロダクション

マイグレーションとはデータベースのバージョンコントロールのようなもので、チームでアプリケーションデータベースのスキーマを簡単に更新し共有できるようにしてくれます。通常、マイグレーションはアプリケーションのデータベーススキーマを簡単に構築できるようにする、Laravelのスキーマビルダーと一緒に使用します。

LaravelのSchemaファサードはテーブルの作成や操作をどのデータベースエンジンを使うかに関わらずサポートします。Laravelがサポートしているデータベースシステム全部で同じ記述法と書きやすいAPIを共用できます。

マイグレーション生成

make:migration Artisanコマンドを使いマイグレーションを生成できます。

php artisan make:migration create_users_table

マイグレーションはdatabase/migrationsフォルダーに設置されます。マイグレーションの実行順をフレームワークに知らせるため、名前にタイムスタンプが含まれています。

--table--createオプションも、テーブル名とマイグレーションで新しいテーブルを生成するかを指定するために使用できます。これらのオプションは生成するマイグレーションスタブの中へ指定したテーブルをただ予め埋め込みます。

php artisan make:migration add_votes_to_users_table --table=users

php artisan make:migration create_users_table --create=users

マイグレーションの生成出力先のパスを指定したい場合は、make:migrateコマンドの実行時に--pathオプションを付けてください。パスはアプリケーションのベースパスからの相対位置です。

マイグレーション構造

マイグレーションはupdownの2メソッドを含んでいます。upメソッドは新しいテーブル、カラム、インデックスをデータベースに追加するために使用し、一方のdownメソッドはupメソッドが行った操作を元に戻します。

両方のメソッドで記述的にテーブルを作成したり、変更したりできるLaravelスキーマビルダーを使えます。Schemaビルダーで使用できる全メソッドは、このドキュメント後半で確認してください。例としてflightsテーブルを作成するマイグレーションを見てください。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateFlightsTable extends Migration
{
    /**
     * マイグレーション実行
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

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

マイグレーション実行

アプリケーションで用意したマイグレーションを全部実行するには、migrate Artisanコマンドを使用します。Homestead仮想マシーンを使用している場合は、VMの中でこのコマンドを実行してください。

php artisan migrate

マイグレーション中に"class not found"エラーが出る場合は、composer dump-autoloadを実行し、その後に再実行してください。

実働環境でのマイグレーション強制

いくつかのマイグレーション操作は破壊的です。つまりデーターを失う可能性があります。実働環境(production)のデータベースでこうしたコマンドが実行されることから保護するために、コマンド実行前に確認のプロンプトが表示されます。コマンド実行時のプロンプトを出さないためには、--forceフラグを指定してください。

php artisan migrate --force

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

最後のマイグレーション「操作」をロールバックしたい場合は、rollbackコマンドを使います。このロールバックで注意してもらいたのは、「一度」に実行した最後のマイグレーションを元に戻すため、複数のマイグレーションファイル分の操作が巻き戻されることがある点です。

php artisan migrate:rollback

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

php artisan migrate:reset

rollbackとmigrateの1コマンド実行

migrate:refreshコマンドは全部のデータベースマイグレーションを最初にロールバックし、それからmigrateコマンドを実行します。このコマンドはデータベース全体を作り直すために便利です。

php artisan migrate:refresh

php artisan migrate:refresh --seed

マイグレーション記述

テーブル作成

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

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

もちろんテーブル作成時には、テーブルのカラムを定義するためにスキーマビルダーのカラムメソッドをどれでも利用できます。

テーブル/カラムの存在チェック

hasTablehasColumnメソッドを使えば、テーブルやカラムの存在を簡単にチェックできます。

if (Schema::hasTable('users')) {
    //
}

if (Schema::hasColumn('users', 'email')) {
    //
}

接続とストレージエンジン

デフォルト接続以外のデータベース接続でスキーマ操作を行いたい場合は、connectionメソッドを使ってください。

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

テーブルのストレージエンジンを指定する場合は、スキーマビルダーのengineプロパティを設定します。

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

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

テーブルリネーム/削除

既存のデータベーステーブルの名前を変えたい場合は、renameメソッドを使います。

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

存在するテーブルを削除する場合は、dropdropIfExistsメソッドを使います。

Schema::drop('users');

Schema::dropIfExists('users');

カラム作成

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

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

使用できるカラムタイプ

当然ながらスキーマビルダーは、テーブルを構築する時に使用する様々なカラムタイプを持っています。

コマンド 説明
$table->bigIncrements('id'); 「符号なしBIGINT」を使用した自動増分ID(主キー)
$table->bigInteger('votes'); BIGINTカラム
$table->binary('data'); BLOBカラム
$table->boolean('confirmed'); BOOLEANカラム
$table->char('name', 4); 長さを指定するCHARカラム
$table->date('created_at'); DATEカラム
$table->dateTime('created_at'); DATETIMEカラム
$table->decimal('amount', 5, 2); 有効/小数点以下桁数指定のDECIMALカラム
$table->double('column', 15, 8); 15桁、小数点以下8桁のDOUBLEカラム
$table->enum('choices', ['foo', 'bar']); ENUMカラム
$table->float('amount'); FLOATカラム
$table->increments('id'); 「符号なしINT」を使用した自動増分ID(主キー)
$table->integer('votes'); INTEGERカラム
$table->json('options'); JSONフィールド
$table->jsonb('options'); JSONBフィールド
$table->longText('description'); LONGTEXTカラム
$table->mediumInteger('numbers'); MEDIUMINTカラム
$table->mediumText('description'); MEDIUMTEXTカラム
$table->morphs('taggable'); INTERGERのtaggable_idと文字列のtaggable_typeを追加
$table->nullableTimestamps(); NULL値を許す以外、timestamps()と同じ
$table->rememberToken(); VARCHAR(100) NULLのremember_tokenを追加
$table->smallInteger('votes'); SMALLINTカラム
$table->softDeletes(); ソフトデリートのためのdeleted_atカラム追加
$table->string('email'); VARCHARカラム
$table->string('name', 100); 長さ指定のVARCHARカラム
$table->text('description'); TEXTカラム
$table->time('sunrise'); TIMEカラム
$table->tinyInteger('numbers'); TINYINTカラム
$table->timestamp('added_on'); TIMESTAMPカラム
$table->timestamps(); created_atupdate_atカラムの追加
$table->uuid('id'); データベース向けのUUID類似値

カラム修飾子

上記のカラムタイプに付け加え、カラムを追加するときに使用できる様々な修飾子もあります。たとえばカラムを「NULL値設定可能(nullable)」にしたい場合は、nullableメソッドを使います。

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

下表が使用可能なカラム修飾子の一覧です。インデックス修飾子は含まれていません。

修飾子 説明
->first() カラムをテーブルの最初(first)に設置する(MySQLのみ)
->after('column') 指定カラムの次にカラムを設置する(MySQLのみ)
->nullable() カラムにNULL値を許す
->default($value) カラムのデフォルト(default)値設定
->unsigned() 整数(integer)を符号(unsigned)

カラム変更

動作要件

カラムを変更する前に、composer.jsonファイルでdoctrine/dbalを確実に追加してください。Doctrine DBALライブラリーは現在のカラムの状態を決め、指定されたカラムに対する修正を行うSQLを生成します。

カラム属性の変更

changeメソッドは存在するカラムを新しいタイプへ変更するか、カラムの属性を変えます。たとえば文字列の長さを増やしたい場合です。changeの実例を見てもらうため、nameカラムのサイズを25から50へ増やしてみます。

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

さらにカラムをNULL値設定可能にしてみましょう。

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

カラム名変更

カラム名を変更するには、renameColumnメソッドをスキーマビルダーで使用してください。カラム名を変更する前に、composer.jsonファイルでdoctrine/dbalを依存パッケージとして追加してください。

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

注意: enumカラムを含んでいるテーブルのカラム名変更は現在サポートしていません。

カラム削除

カラムをドロップするには、スキーマビルダーのdropColumnメソッドを使用します。

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

dropColumnメソッドにカラム名の配列を渡せば、テーブルから複数のカラムをドロップできます。

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

注意 SQLiteデータベースからカラムをドロップする場合は、事前にcomposer.jsonファイルへdoctrine/dbal依存パッケージを追加してください。その後にライブラリーをインストールするため、composer updateを実行してください。

注意: SQLite使用時に、一つのマイグレーションによる複数カラム削除/変更はサポートされていません。

インデックス作成

スキーマビルダーは様々なインデックスタイプをサポートしています。まず指定したカラムの値を一意にする例を見てください。インデックスを作成するには、カラム定義にuniqueメソッドをチェーンで付け加えるだけです。

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

もしくはカラム定義の後でインデックスを作成することも可能です。例を見てください。

$table->unique('email');

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

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

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

コマンド 説明
$table->primary('id'); 主キー追加
$table->primary(['first', 'last']); 複合キー追加
$table->unique('email'); uniqueキー追加
$table->index('state'); 基本的なインデックス追加

インデックス削除

インデックスを削除する場合はインデックスの名前を指定します。Laravelはデフォルトで意味が通る名前をインデックスに付けます。シンプルにテーブル名、インデックスしたカラム名、インデックスタイプをつなげたものです。いくつか例をご覧ください。

コマンド 説明
$table->dropPrimary('users_id_primary'); "users"テーブルから主キーを削除
$table->dropUnique('users_email_unique'); "users"テーブルからユニークキーを削除
$table->dropIndex('geo_state_index'); "geo"テーブルから基本インデックスを削除

カラムの配列をインデックス削除メソッドに渡すと、テーブル、カラム、キータイプに基づき、命名規則に従ったインデックス名が生成されます。

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

外部キー制約

Laravelはデータベースレベルの整合性を強制するために、テーブルに対する外部キー束縛の追加も提供しています。たとえばusersテーブルのidカラムを参照する、postsテーブルのuser_idカラムを定義してみましょう。

Schema::table('posts', function ($table) {
    $table->integer('user_id')->unsigned();

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

さらに束縛に対して「デリート時(on delete)」と「更新時(on update)」に対する処理をオプションとして指定できます。

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

外部キーを削除するには、dropForeignメソッドを使用します。他のインデックスで使用されるものと似た命名規則が、外部キーにも使用されています。つまりテーブル名とカラム名をつなげ、"_foreign"を最後につけた名前になります。

$table->dropForeign('posts_user_id_foreign');

もしくは配列値を渡せば、削除時に自動的に命名規則に従った名前が使用されます。

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

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる