Appearance
リレーション設計 ― 逆に書いたらどうなる?
この章のキーワード
| 用語 | 意味 | なぜ重要か |
|---|---|---|
| hasMany | 「1つの親が複数の子を持つ」リレーション | Friend が複数の PointHistory を持つ |
| belongsTo | 「子が1つの親に属する」リレーション | PointHistory が Friend に属する |
| 外部キー | 別テーブルの主キーを参照するカラム | テーブル間のリレーションを実現する |
| N+1 問題 | メインクエリ 1 回 + リレーション取得 N 回の非効率パターン | 一覧画面で致命的な遅延を招く |
| Eager Loading (with()) | リレーションを事前に一括取得する最適化 | N+1 を 2 クエリに削減 |
Phase 1: 観察
LIBOT の Friend モデル(LINE ユーザー)のリレーション定義を見てみましょう。
php
// Friend.php (excerpt)
// Label: trade-off — リレーション数が多く、N+1リスクを内包している
class Friend extends Model
{
// 1 つの Friend は複数のポイント履歴を持つ
public function point_histories(): HasMany
{
return $this->hasMany(FriendPointHistory::class);
}
// 1 つの Friend は複数の住所を持つ
public function addresses(): HasMany
{
return $this->hasMany(FriendAddress::class);
}
// 1 つの Friend は複数のグループに属する
public function group_details(): HasMany
{
return $this->hasMany(FriendGroupDetail::class);
}
// 1 つの Friend は複数のメッセージを持つ
public function messages(): HasMany
{
return $this->hasMany(Message::class);
}
// タグ(多対多、ポリモーフィック)
public function tags(): MorphToMany
{
return $this->morphToMany(Tag::class, 'taggable');
}
// ... さらに続く(合計 10 以上のリレーション)
}1 つのモデルに 10 以上のリレーション。
Phase 2: 判断
AI禁止ゾーン
hasManyとbelongsToを 逆に書いたら 何が起きますか?(例: Friend が FriendPointHistory に belongsTo)- Friend に 10 以上のリレーション があることのリスクは何ですか?
Friend::all()で 100 件取得し、各 Friend のタグ一覧を表示するとき、SQL は何回実行 されますか?
AIに聞く前に、自分の頭で考えてみましょう。
テキストを入力すると有効になります