Laravelでindexを貼る方法など!(index, unique, primary)

LaravelLaravel

アプリケーションの性能改善などで、indexを貼りたいことがあると思います。
今回はLaravelでマイグレーションを追加して、index・unique・primaryを作成、削除する方法について書いています。
Laravelのバージョン8とMySQLの5.7.36を使って検証しました。

公式ドキュメントの下記の内容を実際に試してみました。
https://laravel.com/docs/8.x/migrations#creating-indexes

今回は、このmembersテーブルにインデックスなどを貼ってみたいと思います。

FieldTypeNullKey
idbigint(20) unsignedNOPRI
namevarchar(255)NO
addressvarchar(512)NO
telvarchar(11)NO
gendertinyint(4)NO
created_attimestampYES
updated_attimestampYES
PR

インデックス(index)を張るには?

インデックスをマイグレーションで作成する方法です。
インデックスはカラムに張ることで、本に索引を用意しておくように、データベースからSELECTするときに検索しやすくする設定です。
うまく使うことで、LaravelなどのWebアプリケーションから検索するときに検索性能が向上します。

インデックスを貼るには、マイグレーションファイルを作成してから貼ると良いです。
マイグレーションを作る時には下記のコマンドを実行します。

$ php artisan make:migration create_index_to_[テーブル名]_table --table=[テーブル名]

テーブル名と書いている箇所に任意のテーブル名を入れます。
これは固定ではないので、ファイル名は他のマイグレーションと被らないわかりやすい名前でつけておけば良いかと思います。

マイグレーションファイルを確認する

今回は、下記のコマンドでmembersnameカラムにインデックスを貼るようにファイルを作成しました。

$ php artisan make:migration create_index_to_members_table --table=members

そうすると、このようにファイルが作成されます。

# php artisan make:migration create_index_to_members_table --table=members
Created Migration: 2021_11_15_122021_create_index_to_members_table

この作成されたファイルのupメソッドとdownメソッドに対して、インデックスに対する操作を書きます。
作成後のファイルを編集して、下記のようにしました。

<?php

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

class CreateIndexToMembersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->index('name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->dropIndex('members_name_index');
        });
    }
}

Schemaファサードクラスのtableメソッドを使用して、インデックスを作成します。

upメソッドの方にクロージャで下記のように記載しました。
indexメソッドに入力しているのはカラム名です。membersテーブルのnameカラムにインデックスが貼られます。

$table->index('name');

downメソッドでロールバックする時には、インデックスが消えるように、下記のように書きました。

$table->dropIndex('members_name_index');

これでロールバックするとインデックスが削除されます。
引数に指定しているのはインデックスの名前です。
$table->indexを使用してインデックスを作ったときは、デフォルトで「テーブル名_カラム名_index」というインデックス名になります。

マイグレーションを実行する

実際に実行してインデックスが貼れているか確認します。
マイグレーションの実行が完了したら下記のようにMigratedになります。

$ php artisan migrate
Migrating: 2021_11_15_122021_create_index_to_members_table
Migrated:  2021_11_15_122021_create_index_to_members_table (47.55ms)

MySQL Workbenchから確認すると、下記のようにインデックスが貼れていることが確認できました。
Laravelでインデックスを貼る

インデックス名を変えたい

インデックスの名前をデフォルトから変えたい場合には、第2引数に好きな名前を入れると良いです。

$table->index('name', 'index_name_test');

複合インデックスを作ると長くなることもあるので、そういう時に使うと良いかと思います。

インデックス(index)を削除するには?

貼ったインデックスを削除する場合、マイグレーションをロールバックすると良いです。
実行するとRolled backと表示されて、ロールバックされたことが確認できます。

$ php artisan migrate:rollback
Rolling back: 2021_11_15_122021_create_index_to_members_table
Rolled back:  2021_11_15_122021_create_index_to_members_table (55.95ms)

dropIndexのカラム名が間違えていると、下記のようなエラーになるので、気をつけてください。

SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'members_name_index'; check that column/key exists (SQL: alter table `members` drop index `members_name_index`)

複合インデックス(index)を張るには?

複合インデックスを作るには、複数のカラムを配列で指定すると良いです。
例えば、membersテーブルのnameaddressに貼る場合は、下記のようになります。

Schema::table('members', function (Blueprint $table) {
    $table->index(['name', 'address']);
});

この場合のインデックス名はカラム名が増えて、members_name_address_indexとなるので、削除する場合は下記のようにします。

Schema::table('members', function (Blueprint $table) {
    $table->dropIndex('members_name_address_index');
});

ユニークキー(unique)を作成するには?

ユニークキーをマイグレーションで作成する方法です。
ユニークキーはカラムに対して、重複を許さないけどNULLを入れることができるカラム設定です。
ユニークキーをカラムに対して作成すると、インデックスも自動で作られます。

インデックスを貼った時と同じようにマイグレーションを作成します。

$ php artisan make:migration create_unique_to_members_table --table=members

membersテーブルのaddressカラムに対して、ユニークキーを作ってみました。
マイグレーションで作成されたファイルを下記のように編集しました。

<?php

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

class CreateUniqueToMembersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->unique('address');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->dropUnique('members_address_unique');
        });
    }
}

インデックスと同じようにSchemaファサードクラスのtableメソッドを使用します。
$table->uniqueでユニークキーが付けれます。

削除する時にはdropUniqueメソッドを使用します。
渡す引数は作成したキー名です。デフォルトで「テーブル名_カラム名_unique」というユニークキー名になります。

マイグレーションを実行する

実際に実行して、確認してみます。インデックスの時と同じようにマイグレーションが流れました。

# php artisan migrate
Migrating: 2021_11_15_130115_create_unique_to_members_table
Migrated:  2021_11_15_130115_create_unique_to_members_table (46.02ms)

このように、Uniqueなインデックスができていることが確認できました。

uniqueキー確認

削除する時には、インデックスの時と同様にロールバックすると削除されます。

主キー(primary)を作成するには?

主キーをマイグレーションで作成する方法です。

主キーはカラムに対して、重複を許さない必須なカラム設定です。
主キーをカラムに対して貼ると、インデックスも自動で作られます。

インデックスを貼った時と同じようにマイグレーションを作成します。

$ php artisan make:migration create_primary_to_members_table --table=members

membersテーブルのtelカラムに主キーを作成してみます。
先に主キーが貼ってあるカラムがあるとエラーになるので、idカラムがない状態でmembersテーブルをマイグレーションして試してみました。

マイグレーションファイルは下記のように編集しました。

<?php

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

class CreatePrimaryToMembersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->primary('tel');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('members', function (Blueprint $table) {
            $table->dropPrimary('tel');
        });
    }
}

インデックスの時と同様にして、tableメソッドの第2引数のクロージャに処理を書きます。
primaryメソッドを使用して、$table->primaryとすると主キーが作成できます。
渡す引数はカラム名です。

$table->primary('tel');

消したい時にはdropPrimaryメソッドを使います。

$table->dropPrimary('tel');

こちらもカラム名を指定すると削除できました。

マイグレーションを実行する

実際に主キーが作成できたか確認します。
マイグレーションを下記のように流しました。

$ php artisan migrate
Migrating: 2021_11_15_131439_create_primary_to_members_table
Migrated:  2021_11_15_131439_create_primary_to_members_table (66.50ms)

このようにtelカラムが主キーになっていることが確認できました。
Laravelで主キーを作成する

コメント

タイトルとURLをコピーしました