RitoLabo

Laravelのマイグレーション&スキーマビルダでDBのテーブルやカラムを作成する

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,migration,SchemaBuilder,5.5,5.4,5.3,5.6,5.7

今回はLaravelのmigration(マイグレーション)機能とスキーマビルダを使ってデータベースのテーブルやカラムを管理する一連の流れを行います。
今回は、テーブルの追加編です。

アジェンダ
  1. 開発環境
  2. マイグレーションについて
  3. データベース接続確認
  4. マイグレーションファイルの生成
  5. マイグレーションクラス実装
    1. スキーマビルダ
      1. カラムタイプ
  6. マイグレーション実行
  7. ロールバック

開発環境

今回の開発環境は以下の通りです。

  • linux CentOS 7.2
  • Apache 2.4
  • PHP 7.2/7.1
  • MySQL 5.7

Laravelのルートディレクトリを「laravel」とします。

また、Laravelのバージョンに関しては、5.7/5.6/5.5/5.4/5.3にて検証済みです。

マイグレーションについて

Laravelに限りませんが、マイグレーションとは、PHPフレームワーク内でのスクリプトを用いてデータベース情報を管理していく事です。通常、データベースを構築するには、MySQLへログインし、SQL文を発行し、開発ならテストデータを入れて…などといった工程がありますが、Laravelでは、このマイグレーション機能を使えば、それをコマンド1発で、しかも何度でも同じ状態を作る事が出来るという優れた機能です。(もちろん、一部追加や削除なども)

マイグレーションは昨今のPHPフレームワークであれば大抵は入っている機能でもあります。
ちなみに、マイグレーションについての色々な紹介を見ていると、チーム開発などで力を発揮するといった記述が多く、それは正にその通りなのですが、個人で開発する場合でも多いに活躍してくれる機能である事は間違いないありません。

データベース接続確認

マイグレーション機能の導入前に、LaravelがDBに接続出来ている事が最低限必要なので、まだ接続していない場合は、envファイルを開いて接続情報を記載してください。MySQLの場合は以下の部分です。

laravel/.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1 # ホスト名
DB_PORT=3306 # ポート番号
DB_DATABASE=homestead # データベース名
DB_USERNAME=homestead # ユーザ名
DB_PASSWORD=secret # パスワード

ちなみにここで接続するデータベースですが、実態さえあれば良いので、もし練習や実験用という事であれば空っぽのデータベースでOKです。

マイグレーションファイルの生成

まず、設定を記述するマイグレーションを生成します。生成するマイグレーションですが、基本的には作成するテーブル1つにつき1つのマイグレーションファイルを生成します。(カラム追加等は別)

つまり、1つのマイグレーションファイルに2つ以上のテーブル作成の構築情報は書きません。

Artisanコマンドを使って生成しますが、書式は以下になります。

php artisan make:migration create_[ここにテーブル名]_table  --create=[テーブル名]

「create_[ここにテーブル名]_table」の部分にマイグレーションの名前を決めて入力します。

ちなみに、先頭と末尾の「create_」「_table」に関してはべつに無くても良いのですが、こういった固定の接頭辞(プレフィクス)や接尾辞(サフィクス)、そしてテーブル名を入れておけば、「これは○○テーブルのマイグレーションファイルだよ」と一目でわかるので私は入れるようにしています。
(ちなみに「create_」「_table」に関しては、公式の記述に倣っています)

それと、ここでの名前は、これから生成するマイグレーションファイルのクラス名に直結してくるので、その辺も考えてつけましょう。

例)
マイグレーション名をcreate_users_tableとすると、クラス名はCreateUsersTableになります。

そして、テーブル名をcreateオプション(--create)に記述します。

このcreateオプションは、Schemaクラスのメソッド(テーブルを作成するcreateメソッド)を指定しています。これは、テーブルを新たに作成するマイグレーションファイルを作成する際に指定するオプションです。このオプションを見てマイグレーション内のメソッドが生成されます。

という事で、今回は「create_books_table」にしようと思います。

早速、Laravelルートディレクトリにて、コマンドを叩きます。

# Laravelのルートディレクトリへ移動
cd /path/to/laravel

# マイグレーション生成
php artisan make:migration create_books_table --create=books

# 実行結果
[demo@localhost laravel]# php artisan make:migration create_books_table --create=books
Created Migration: 2018_11_24_172221_create_books_table

エラーなく生成出来たでしょうか?生成されたマイグレーションファイルですが、 laravel/database/migrations 配下に生成されていれば成功です。

laravel
├─ database
├─ migrations
├─ 2014_10_12_000000_create_users_table.php
├─ 2014_10_12_100000_create_password_resets_table.php
└─
2018_11_24_172221_create_books_table.php // ← ココ

マイグレーションクラス実装

それでは生成されたマイグレーションファイルをエディターで開いてみましょう

<?php

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

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

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

テーブル名もしっかりセットされていて、いい感じです。

このファイルにテーブルの構築情報を記述していくのですが、メソッドが2つあります。 簡単に言ってしまえば、upメソッドでテーブルを構築し、downメソッドでテーブルを壊すので、記述自体はupメソッドに行っていきます。 という事で、こんな感じで書いてみました。

public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->increments('id')->comment('主キー');
$table->string('book_name', 255)->comment('本の名前');
$table->string('author', 100)->index('index_author')->comment('作者・筆者');
$table->integer('price')->comment('価格');
$table->integer('stocks')->index('index_stocks')->comment('在庫数');
$table->timestamp('release_dt')->comment('発売日');
$table->timestamps();
});
}

ちなみにこの、クロージャの中に記載されている「$table->string(...」の部分がいわゆる「スキーマビルダ」と呼ばれるものになります。

スキーマビルダ

スキーマビルダとは、テーブル作成の際の式を簡単シンプルに組み立てられるLaravelの便利機能のことです。これにより、複雑なSQL文を組み立てなくてもテーブル・カラム定義を行う事が出来ます。

カラムタイプについて

スキーマビルダで記述していく際に、指定できるカラムタイプの一部を以下に示します。

$table->increments('id');
オートインクリメント(自動増分)を付与した主キー
$table->string('book_name', 255)
「VARCHAR」タイプ。カラム名「book_name」で、最大文字数を「255」文字で設定しています。
$table->integer('price')
「INT」タイプ。引数はカラム名のみです。
$table->text('body');
「TEXT」タイプ。
$table->timestamps();
このカラムタイプを指定した場合、Timestamp型の「created_at」と「updated_at」が2つ生成されます。

上記例で使っているのはこれくらいですが、全てのカラムタイプ記法を以下に示します。

public function up()
{
Schema::create('sample_column_types', function (Blueprint $table) {
/**
* AUTO_INCREMENT(自動増分ID/UNSIGNED(符号なし)
*/
$table->tinyIncrements('id'); // TINYINT
$table->smallIncrements('id'); // SMALLINT
$table->increments('id'); // INT
$table->mediumIncrements('id'); // MEDIUMINT
$table->bigIncrements('id'); // BIGINT

/**
* 数値型
*/
$table->tinyInteger('votes'); // TINYINT
$table->smallInteger('votes'); // SMALLINT
$table->integer('votes'); // INTEGER
$table->mediumInteger('votes'); // MEDIUMINT
$table->bigInteger('votes'); // BIGINT

/**
* 数値型/UNSIGNED(符号なし)
*/
$table->unsignedTinyInteger('votes'); // TINYINT
$table->unsignedSmallInteger('votes'); // SMALLINT
$table->unsignedInteger('votes'); // INT
$table->unsignedMediumInteger('votes'); // MEDIUMINT
$table->unsignedBigInteger('votes'); // BIGINT

/**
* 可変長文字列型
*/
$table->string('name', 100); // VARCHAR

/**
* 固定長文字列型
*/
$table->char('name', 100); // CHAR

/**
* TEXT
*/
$table->text('description'); // TEXT
$table->mediumText('description'); // MEDIUMTEXT
$table->longText('description'); // LONGTEXT

/**
* BLOB(バイナリデータ)型
*/
$table->binary('data'); // BLOB

/**
* Boolean
*/
$table->boolean('confirmed'); // BOOLEAN

/**
* 日時系
*/
$table->year('birth_year'); // YEAR
$table->date('created_at'); // DATE
$table->dateTime('created_at'); // DATETIME
$table->dateTimeTz('created_at'); // DATETIME/タイムゾーン付き
$table->time('sunrise'); // TIME
$table->timeTz('sunrise'); // TIME/タイムゾーン付き
$table->timestamp('added_on'); // TIMESTAMP
$table->timestampTz('added_on'); // TIMESTAMP/タイムゾーン付き

/**
* created_atupdated_atカラム追加用
*/
$table->timestamps(); // NULL値許容
$table->nullableTimestamps(); // timestamps()と同じ
$table->timestampsTz(); // NULL値許容/タイムゾーン付き

/**
* ソフトデリート用deleted_atカラム追加用/NULL値許容
*/
$table->softDeletes(); // TIMESTAMP
$table->softDeletesTz(); // TIMESTAMP/タイムゾーン付き

/**
* Geometry
*/
$table->geometry('positions'); // GEOMETRY
$table->geometryCollection('positions'); // GEOMETRYCOLLECTION

/**
* LineString
*/
$table->lineString('positions'); // LINESTRING
$table->multiLineString('positions'); // MULTILINESTRING

/**
* 空間系
*/
$table->point('position'); // POINT
$table->multiPoint('positions'); // MULTIPOINT
$table->polygon('positions'); // POLYGON
$table->multiPolygon('positions'); // MULTIPOLYGON

/**
* アドレス系
*/
$table->ipAddress('visitor'); // IP_ADDRESS
$table->macAddress('device'); // MAC_ADDRESS

/**
* Json
*/
$table->json('options'); // JSON
$table->jsonb('options'); // JSONB

/**
* 列挙型
*/
$table->enum('level', ['easy', 'hard']); // ENUMカラム

/**
* Float
*/
$table->decimal('amount', 8, 2); // DECIMAL
$table->unsignedDecimal('amount', 8, 2); // DECIMAL/符号なし
$table->double('amount', 8, 2); // DOUBLE
$table->float('amount', 8, 2); // FLOAT

/**
* taggable_idINTERGER/UNSIGNED)&taggable_type(文字列)追加用
*/
$table->morphs('taggable');
$table->nullableMorphs('taggable'); // morphs()NULL値許容

/**
* UUIDカラム追加用
*/
$table->uuid('id'); // UUID

/**
* remember_tokenカラム追加用
*/
$table->rememberToken(); // VARCHAR(100)/NULL値許容
});
}

上記だけでなく、全てのカラムタイプ・カラム修飾子・インデックス修飾子をまとめたものをGithubに公開していますのでよかったら参考にしてください。
[Github]rito-nishino/Laravel-Migration-SchemaBuilder-ColumnTypes-List

マイグレーション実行

スキーマビルダでupメソッドを実装できたら、さっそくマイグレーションを実行してみましょう。
マイグレーション実行にはArtisanコマンドを叩きます。
Laravelルートディレクトリにて、以下のコマンドを実行してみてください。

# Laravelのルートディレクトリへ移動
cd /path/to/laravel

# マイグレーション実行
php artisan migrate

# 実行結果
[demo@localhost laravel]# php artisan migrate
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrating: 2018_11_24_172221_create_books_table // ← 今回作成したマイグレーションが実行されている
Migrated: 2018_11_24_172221_create_books_table

作成したマイグレーションが実行された事が確認できたでしょうか?
実際にMySQLにログインしてデータベースを見てみましょう。

# マイグレーション実行後
mysql> show columns from books;
+------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+-------------------+-----------------------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| book_name | varchar(255) | NO | | NULL | |
| author | varchar(100) | NO | MUL | NULL | |
| price | int(11) | NO | | NULL | |
| stocks | int(11) | NO | MUL | NULL | |
| release_dt | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------+------------------+------+-----+-------------------+-----------------------------+

bookテーブルが設定したカラム構成で構築されていますね。

ロールバック

マイグレーションでデータベース管理を行う事の利点の一つに、「ロールバック」を行える事が挙げられます。 ロールバックを行うと、これまで行ってきたマイグレーションを遡って、データベースを元に戻す(なかった事にする)事が出来ます。
基本は以下のコマンドです。

# 一番最後に実行したマイグレーションが無かったことになる
php artisan migrate:rollback

また、ロールバックは、引数を付ける事で何段階戻すかを指定する事が出来ます。こんな感じです

# マイグレーションを3世代前にロールバックする
php artisan migrate:rollback --step=3

その他にも以下のようなロールバックも行えます。

全てのマイグレーションをロールバックする
# 全てのマイグレーションをロールバックする
php artisan migrate:reset
全てのマイグレーションをロールバックし、再度マイグレーションを実行する
# 全てのマイグレーションをロールバックし、再度マイグレーションを実行する
php artisan migrate:refresh

ロールバックして元に戻したとしても、またマイグレーションを実行すれば再構築する事ができます。
今回はロールバックは手順として行いませんが、参考として覚えておいてください。

まとめ

いかがでしたでしょうか? 今回は、マイグレーションでテーブルを作成するまでを行いました。
次回は、同じくマイグレーションで、今回作成したテーブルのカラムを操作(変更や追加)を行います。

next:Laravelのmigration(マイグレーション)でテーブルのカラムを追加・変更・削除する