0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Laravelでデータべースに複合インデックスを貼ったり削除したりする

Posted at

背景

Laravel8でマイグレーションを使ってインデックスをいろいろ操作するのってどうするんだろうと調べたときのメモ。
既存テーブルに複合インデックスを追加するのが主な目的。

実行環境

Laravel: 8.65
MySQL:8.0

やりたい事

  • Laravelでマイグレーションを使ってDBインデックスの貼りたい(複合インデックス)
    • 新規(テーブル作成時)
    • 追加(テーブル作成後)
    • 削除

作業手順

  • マイグレーションファイルを手動でつくる。中身の編集は手動。ファイルができたら手動でphp artisan migrateする。

  • Laravelが作成したインデックス名はデフォルトで以下の名称になる。独自指定も可能。

インデックス名 : テーブル名__インデックスしたカラム名__インデックスタイプ

インデックスの追加方法いろいろ

事前に調べてみるとインデックスを作成するには以下の様な指定をすると作成できそう。
また、primaryキーを削除したり、uniqueインデックスを削除する、といったメソッドもあるよう。

①1つのカラム名だけを指定してインデックスを作成する。実際に作成されるインデックス名はLaravelに任せる。

$table->index('user_name');

② 1つのカラム名を指定してインデックスを作成する。実際に作成されるインデックス名は指定された名前になる。

$table->index('user_name','idx_user_name');

③ 複数のカラム名を指定して複合インデックスを作成する。複数指定する場合は配列として指定する。

$table->index(['user_name', 'department']);

新規(テーブル作成時)

普通にテーブル定義した後にインデックスを追加する。※テーブルの意味は適当です

        Schema::create('accounts', function (Blueprint $table) {
            $table->id();
            $table->string('user_name',20)->unique();
            $table->string('department',20);
            $table->index(['user_name', 'department']); // ←複合インデックス追加

追加(テーブル作成後)

  • マイグレーションファイル追加

インデックス名称はLaravelがデフォルトのものをつけてくれる。

$ php artisan make:migration add_index_to_accounts --table=accounts
  • 上記で作成されたマイグレーションファイルを開き、up()とdown()を以下の様に修正する。
database/migrations/YYYY_MM_DD_TIME_add_index_to_acconts.php

    public function up()
    {
        Schema::table('accounts', function (Blueprint $table) {
            // 複合インデックスを追加。名称はLaravelに任せる。
            $table->index(['user_name', 'department']);
        });
    }

    public function down()
    {
        Schema::table('accounts', function (Blueprint $table) {
            // カラム名のみを指定。名称はLaravelに任せる
            $table->dropIndex(['user_name', 'department']);
        });
    }

マイグレーション実行

# マイグレーション実行
php artisan migrate
# DBを確認すると複合インデックスが作成されている。

インデックス削除

# マイグレーションロールバック
php artisan migrate:rollback --step=1
# DBを確認すると複合インデックスが削除されている。

気を付けるポイント

  • 通常、DBに付与されるインデックス名はLaravelのデフォルトできまる。なので作成時にインデックス名は分からない(ルールに沿った名称がつけられるが)。
  • 削除時もルールに沿った名称で削除してほしかったらカラム名を配列で指定する。
  • こちらの方がルールを意識せずにしていできるのでよさげ。
    ※ただし、該当カラムに外部キーが指定してある場合にインデックスを削除しようとする(rollback)と、MySQLでは1553エラーがでるようなので、先に外部キーを削除するようにマイグレーションファイルを記載する。つまり外部キーの作成もこのインデックス追加のマイグレーションとセットですることが望ましいと思われる。

SQLSTATE[HY000]: General error: 1553 Cannot drop index

参考記事

Laravel でインデックスを作成、削除する
https://qiita.com/sato_ryu/items/311df38b81ab427447ca

Laravel 8.x マイグレーション
https://readouble.com/laravel/8.x/ja/migrations.html

【Laravel】初めてのマイグレーション
https://qiita.com/manbolila/items/c19735438affefbfbe69

MySQL スロークエリ改善 初心者向け
https://zenn.dev/ohkisuguru/articles/48dff6cf195244

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?