RDB

Laravel5 複合主キー

 

 

複合主キーはどういう時利用するの?

 

履歴系

  • 購入者id + 商品id + 購入日時
  • WordPress『wp_term_relationships』テーブル
    外部テーブルのサロゲートキーを集中管理

 

ターゲット系

例 プッシュ通知でのお知らせ

  • お知らせテーブル
  • お知らせターゲットテーブル

お知らせターゲットテーブルはお知らせidとお知らせするuser_idでの複合主キーになります。

 

noticesテーブル

<?php

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

class CreateNoticesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('notices', function (Blueprint $table) {
            $table->bigIncrements('notice_id')->comment('主キー');
            $table->string('name', 255)->comment('お知らせ名');
            $table->string('notice_thumbnail_filename', 255)->comment('お知らせサムネイル名');
            $table->string('notice_thumbnail_path', 1000)->comment('お知らせサムネイル名');
            $table->text('main_text')->comment('お知らせ本文');
            $table->boolean('push_send_flag')->default(0)->comment('お知らせ送信フラグ');
            $table->string('detail_link_url', 1000)->comment('お知らせ詳細URL');
            $table->boolean('important_flag')->default(0)->comment('重要フラグ');
            $table->integer('regist_sys_user_id')->nullable()->comment('登録を行ったシステム管理者id');
            $table->timestamp('created_at')->nullable()->comment('作成日時');
            $table->integer('update_sys_user_id')->comment('更新を行ったシステム管理者id');
            $table->timestamp('updated_at')->nullable()->comment('更新日時');
            $table->integer('delete_sys_user_id')->nullable()->comment('削除を行ったシステム管理者id');
            $table->timestamp('deleted_at')->nullable()->comment('削除日時');
        });
    }

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

 

notice_targetsテーブル

<?php

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

class CreateNoticeTargetsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('notice_targets', function (Blueprint $table) {
            $table->bigInteger('notice_id')->comment('複合主キー:noticesテーブル外部キー');
            $table->bigInteger('user_id')->comment('複合主キー:usersテーブル外部キー');
            $table->boolean('is_read_flag')->default(0)->comment('既読フラグ');
            $table->integer('regist_sys_user_id')->nullable()->comment('登録を行ったシステム管理者id');
            $table->timestamp('created_at')->nullable()->comment('作成日時');
            $table->integer('update_sys_user_id')->comment('更新を行ったシステム管理者id');
            $table->timestamp('updated_at')->nullable()->comment('更新日時');

            $table->primary(['notice_id', 'user_id'])->comment('複合主キー定義'); // 暗黙のINDEXのnotice_id
            $table->index('user_id'); // user_idカラムもINDEXを追加
        });
    }

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

 

ポイント

 

            $table->primary(['notice_id', 'user_id'])->comment('複合主キー定義'); // 暗黙のINDEXのnotice_id
            $table->index('user_id'); // ●user_idカラムもINDEXを追加

先頭のnotice_idは暗黙のINDEXがかかるが、user_idにはINDEXが貼られない。

別途で定義する。

 

Laravelでの複合主キー

なかなか大変😇

INSERTはできるが、UPDATEやsave()で問題がでる。

作法としてサロゲートを使って欲しい模様。

 

頑張って対応

 

解決① クエリビルダを利用する

 

@see

 

解決策② Traitを利用する

 

@see

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)