Blog

DB のリレーション

DB のリレーション

システム開発する上で、DB のリレーションは便利です。
今回は、私が Laravel でシステム開発したときのことをまとめています。

リレーションを組むことこそ、DBの真骨頂ですからね。
最大限にパワーを発揮できるように、理解したいと思います。

マイグレーション

「Items」テーブルに「Users」の主キー「id」を紐づけしたいと考えました。
以下の図のようなイメージですね。

Users テーブルはデフォルトで作られているため、特に変更せず
今回は Items テーブルのマイグレーションから作成していきます。

create_items_tableの作成

1.プロジェクトフォルダで、ターミナルを開きます。

$ cd test // 現在の階層の中のtest(フォルダ)に移動する

2.ターミナルで以下のコマンドを叩きます。

$ php artisan make:migration create_items_table

※create_(作成したいテーブル名)_table で作成します。
 また、テーブル名は 複数形 、モデル名は 単数形 を使います。

これにより、database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.phpが生成されます。
YYYY_mm_dd_XXXXXXには作成した日時が入ります。

カラムの編集および外部キーの設定

database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.phpup()を編集します。

database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php

    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->text('text')->nullable();
            $table->bigInteger('user_id');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }

これで外部キーとして渡すことができます。

抜粋

$table->foreign('user_id')->references('id')->on('users');
// $table->foreign(外部キーカラム)->references(主キーカラム)->on(主キーテーブル);

しかし、
これだけでは上手くいかないんです。

->unsigned()の追加

POINT

実は->bigIncrements()で指定されている主キーは自動でUNSIGNEDが追加されています。
そのため、外部キーでも指定が必要です。

database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php

            $table->bigInteger('user_id')->unsigned();

これで、外部キーが正常に渡せる状態になりました。


モデルのリレーション

これで DB のリレーション自体は完了しているのですが、
もう少し呼び出しやすくするために、各テーブルのモデル同士でもリレーションを組んでいきます。

モデルの作成

すでにデフォルトで「User モデル」が存在するため、今回は「Item モデル」を作成します。

$ php artisan make:model Item

これで、app/Item.phpが生成されます。

リレーションの設定

さて、リレーションを設定する訳なのですが、
ここで改めて「Users」と「Items」の関係をイメージしてみます。

このようなイメージですね。
各 User がいくつかの Item を持っている状態をイメージしています。

ここで大事なのは、

  • 何が何を持っているのか
  • 1:1?  1:多? 多:多?

という情報です。

POINT

今回でいうと、
「一人のUserが複数のItemを持っている → 1:多」です。

それぞれリレーションの設定方法が違うので、注意してください。
今回他は割愛し、1:多のみを説明します。

他の情報が欲しい方はLaravel 公式を参照してください。

まずは、主体となる「Users」の方から追記します。
以下のコードを追加してください。

app/User.php

class User extends Authenticatable
{

----------(略)----------

+   public function items()
+   {
+       return $this->hasMany('App\Item');
+   }

}

次に、「Items」の方です。
呼び出すメソッドが違うため注意してください。

app/Item.php

class Task extends Model
{

+   public function user()
+   {
+       return $this->belongsTo('App\User');
+   }

}

これでリレーションが設定できました。


リレーションを使った呼び出し

最後にこのリレーションを使って呼び出す方法も記載しておきます。

「山田太郎」の「item」を取得
use App\User;

$user = User::where("name", "山田太郎");
$items = $user->items()->get();

これで山田太郎が持つ「item」を全て取得することができます。

use App\User;

$items = User::where("name", "山田太郎")->items()->get();

これも可能です。

リレーションを設定していない場合

リレーションを設定していない場合

use App\User;
use App\Item;

$user = User::where("name", "山田太郎")->first();
$items = Item::where("user_id", $user->id)->get();

両方呼び出す必要が出てきます。

POINT

$user->items()->get()の方が
このユーザのアイテムをゲットと分かりやすいですね。


今回は比較的簡単なDB設計だと思います。

もっと大掛かりなシステムとなれば、リレーションも複雑になったり
多:多なども出てくることと思います。

POINT

そのため、ER図(Entity Relationship)を描いたりして、
しっかりと頭の中でもイメージを明確に持つことは重要だと感じました。

最後まで読んでいただき、ありがとうございました。

MeisterGuild(マイスター・ギルド)広報

最先端技術のMEISTERを目指し、お互い切磋琢磨するGUILD、になりたい株式会社マイスター・ギルドです。Webシステム/サービス開発、スマホアプリ開発、AR/VR/MR開発など、さまざまな情報を発信します。

Related Entry