[Laravel][Homestead] マイグレーションしてみる


## マイグレーションとは

データベースのバージョンコントロールのようなもの。
マイグレーションファイルを準備して、マイグレーションを実行することでテーブルの反映やロールバックをすることができます。

## マイグレーションファイルの場所

マイグレーションファイルは`database/migrations/`に配置します。初期状態で2つのファイルが用意されています。

```
./
└database
　└migrations
　　　2018 2014_10_12_000000_create_users_table.php*
　　　2018 2014_10_12_100000_create_password_resets_table.php*
```

## マイグレーションを実行してみる

以下のコマンドを実行すると`database/migrations`フォルダ下のマイグレーションファイルのうち、まだ反映されていないものが一括反映されます。

```
$ php artisan migrate
```

マイグレーションを強制する場合は、--forceフラグを指定します。

```
$ php artisan migrate --force
```

直前に実行した反映を取り消したい場合は、ロールバックを実行します。

```
$ php artisan migrate:rollback
```

直近の数回の実行を取り消したい場合、--stepフラグを指定します。

```
$ php artisan migrate:rollback --step=5
```

全てのマイグレーションをまとめて取り消す場合は、リセットを実行します。

```
$ php artisan migrate:reset
```

## migrationファイルの作成

以下のコマンドを実行してマイグレーションファイルを作成します。指定するファイル名を「create_hoge_table」にすると、hogeテーブルを作成するためのコマンドが追加されます。

```
$ php artisan make:migration create_hoge_table
Created Migration: 2019_07_08_072918_create_hoge_table
```

コマンドが成功すると、`database/migrations`にファイルが作成されます。
マイグレーションはupとdownのメソッドを含んでいます。
upは追加や変更処理を実行し、downはupメソッドが行った操作を元に戻します。

```php:2019_07_08_072918_create_hoge_table
<?php

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

class CreateHogeTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('hoge', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('hoge');
    }
}
```

## テーブルを定義してみる

マイグレーションファイルのテーブル定義はupメソッドに記述する。

### カラムタイプ

使いそうなものを列挙。

|コマンド|説明|
|:--|:--|
|$table->bigIncrements("id");|符号なしBIGINTインクリメント|
|$table->bigInteger("votes");|BIGINT|
|$table->binary("data");|BLOB|
|$table->boolean("confirmed");|BOOLEAN|
|$table->char("name", 100);|CHAR|
|$table->date("created_at");|DATE|
|$table->dateTime("created_at");|DATETIME|
|$table->dateTimeTz("created_at");|DATETIME(タイムゾーン付き)|
|$table->decimal("amount", 8, 2);|DECIMAL|
|$table->double("amount", 8, 2);|DOUBLE|
|$table->float("amount", 8, 2);|FLOAT|
|$table->integer("votes");|INTEGER|
|$table->smallInteger("votes");|SMALLINT|
|$table->string("name", 100);|VARCHAR|
|$table->text("description");|TEXT|
|$table->time("sunrise");|TIME|
|$table->timeTz("sunrise");|TIME(タイムゾーン付き)|
|$table->timestamp("added_on");|TIMESTAMP|
|$table->timestampTz("added_on");|TIMESTAMP(タイムゾーン付き)|

### カラム修飾子

使いそうなものを列挙。

|コマンド|説明|
|:--|:--|
|->default($value)|デフォルト値を設定|
|->nullable($value = true)|デフォルトでNULL値を挿入する|
|->useCurrent()|TIMESTAMPのデフォルトにCURRENT_TIMESTAMPを指定|

### インデックス修飾子

使いそうなものを列挙。

|コマンド|説明|
|:--|:--|
|$table->primary("id");|主キー追加|
|$table->primary(["id", "parent_id"]);|複合キー追加|
|$table->unique("email");|uniqueキー追加|
|$table->index("state");|インデックス追加|

### 外部キー制約

postsテーブルのuser_idが、usersテーブルのidを参照している場合、次の通り定義する。

```
Schema::table('posts', function (Blueprint $table) {
    $table->unsignedInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users');
}
```

「削除時(on delete)」と「更新時(on update)」に対する処理をオプション指定することもできる。

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



以上を踏まえて実際にテーブルを定義してみる。

```php:2019_07_08_072918_create_hoge_table
<?php

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

class CreateHogeTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('hoge', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name', 20);
            $table->string('mail', 256);
            $table->text('comment')->nullable();
            $table->char('type', 1)->default('C');
            $table->timestamps();

            $table->unique('mail');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('hoge');
    }
}
```

## 参考

[Laravel Document](https://readouble.com/laravel/5.5/ja/migrations.html)