Help us understand the problem. What is going on with this article?

LaravelでPrimaryKeyが複数で片方がIncrementのテーブルを作るmigration

More than 1 year has passed since last update.

目的

  • primary_keyが複数ある。
  • idはオートインクリメントにしたい。
  • LaravelのMigartionを使いたい。

と、設定されたテーブルを作りたいので...

実際の実装

マイグレーションのサンプルコード
2018_06_21_172946_create_examples_table.php
<?php

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

class CreateOrderSourcesTable extends Migration
{
    const TABLE_NAME = 'examples';

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create(self::TABLE_NAME, function (Blueprint $table) {            
            $table->unsignedBigInteger('id');
            $table->unsignedBigInteger('parent_id');
            $table->unsignedTinyInteger('example_data');

            $table->primary(['id', 'parent_id']);
        });

        Schema::table(self::TABLE_NAME, function (Blueprint $table) {
            // 1個目の引数がカラム名、2個目がインクリメント、3個目がunsigned flag
            $table->BigInteger('id', true, true)->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop(self::TABLE_NAME);

        /**
         * SEQUENCEを削除する。
         * 自動生成では {テーブル名}_{インクリメントされたカラム}_
         */
        \DB::statement('DROP SEQUENCE '.self::TABLE_NAME.'_id_seq');
    }
}

解説

未検証ですが、おそらくincement()で主キーのカラムを一個作り、
ALTERでもう一つカラムを追加するやり方でも出来るかもしれません。

重要なポイント

up()

  • 先にincrement()か、primary()で主キーを一個定義してしまうと、
    2個目は「主キーが既にある」として、エラーになってしまいます。
 SQLSTATE[42P16]: Invalid table definition: 7
 ERROR:  multiple primary keys for table "example" are not allowed
 (SQL: alter table "example" add primary key ("secondery_id"))
  • そこで、BigInteger()でidを定義し、
    $table->primary([]);の構文で複数に主キーを指定します。
  • そして必要なカラムを後からインクリメントに変更します。
  • サンプルコードのコメントで記載してあるように、
    Integer(), BigIntegerは第2~3の引数で設定を変えられます。

drop()

  • Sequenceが残っているとrollbackして再びmigrateした際に、下記のようなエラーになります。
cli
> php artisan migrate
> php artisan migrate:rollback
> php artisan migrate
 SQLSTATE[42P07]: Duplicate table: 7 ERROR:
  relation "order_examples_id_seq" already exists
 (SQL: CREATE SEQUENCE order_items_id_seq)

  • このため、dropする際はDROP SEQUENCEを直接実行しています。
    これは、複合キーの場合はSchema::dropしただけでは消えなかったこと、
    dropPrimary(), bigInteger()などで主キーを解除しても消えなかったためです。
t_mitarai
地獄から甦ったサーバーサイド開発忍者 ソースコードの半角スペースを空文字に置換し、 ランダムな位置に全角スペースを埋め込むのを生業にしている
https://blog.t-mitarai.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away