🔐

「JOINは構造に従うべき」– SQL設計で外部キーとリレーションの自然さに気づいた話

に公開

はじめに

最近、番組表をテーマにしたデータベースを設計していた際に、
外部キーやJOINの“書きやすさ”と“自然さ”の大切さに気づく出来事がありました。

JOINが繋がらない。JOINできても構造が不自然。
そんな問題の正体は、リレーションの設計ミスや外部キーの欠如でした。

この記事では、実際に体験した設計ミスと学びをもとに、
**「JOINは構造に従って書くべき」**という原則についてまとめます。


💡 どんなテーブル設計だったのか?(全体像)

今回は、インターネットTVサービス(例:ABEMA)のような番組表データベースを設計していました。
番組・ジャンル・エピソード・スケジュールなどをリレーショナルに扱います。

🔹 ER構造

channel ─┬─────────────┐
│ │
▼ ▼
program schedule
│ ▲
│ │
▼ │
season ──▶ episode ──▶ schedule
│ ▲
└──────────────────────────┘

program ──┬──────────────▶ program_genre ◀────────────── genre

🔸 テーブルの概要

テーブル名 役割
channel チャンネル情報(例:アニメ1、ドラマなど)
program 番組の基本情報(例:鬼滅の刃、ドクターX)
season 番組のシーズン管理
episode 各話エピソード情報
genre 番組のジャンル(アニメ、ドラマなど)
program_genre 番組とジャンルをつなぐ中間テーブル
schedule どのチャンネルでどのエピソードがいつ放送されるか

🤦‍♂️ JOINが繋がらない事件

最初、program テーブルには channel_id を定義していませんでした。

CREATE TABLE program (
  id BIGINT PRIMARY KEY,
  title VARCHAR(200),
  description TEXT
);

そのときは「スケジュールにチャンネル情報あるし、繋げればいいでしょ」と思っていました。

しかし JOIN を書いてみると……

SELECT program.title, channel.name
FROM program
JOIN channel ON ??? -- ← 繋がらない!

当然です。番組がどのチャンネルに属しているかという“関係”がどこにもないからです。

✅ 外部キーを追加して構造が自然に

ALTER TABLE program ADD COLUMN channel_id BIGINT;

ALTER TABLE program
ADD CONSTRAINT fk_program_channel
FOREIGN KEY (channel_id) REFERENCES channel(id)
ON DELETE SET NULL ON UPDATE CASCADE;

以降は以下のようにJOINでき、構造的にも意味が明確になります。

SELECT program.title, channel.name
FROM program
JOIN channel ON program.channel_id = channel.id;

🔁 中間テーブルJOINの“順序”にも注意が必要だった

ジャンルとの多対多リレーションを組んでいる program_genre でも気づきがありました。

-- ❌ 悪い例(読み手が混乱)
JOIN program_genre ON genre.id = program_genre.genre_id

これは**「目的地から逆流している」**ように見えて読みづらいです。

-- ✅ 良い例(流れが自然)
JOIN program_genre ON program.id = program_genre.program_id
JOIN genre ON program_genre.genre_id = genre.id

構造の流れが一方向に読み取れると、JOINの意味が即座に理解できます。

🧭 中心にするテーブルの考え方

「番組表」を主軸にするなら、すべての放送情報が集まっている schedule を中心にするのが自然です。

program_idchannel_idepisode_idstart_time、views などが集約されている

これを起点にJOINすれば、ユーザーが知りたい「いつ・何が・どこで」すべて取得できます。

💡 設計して、書いて、初めて気づくこと

SQLを書いてみてはじめて、
「ここに外部キーがないとJOINできない」
「このJOINは構造が逆流していて読みにくい」
といった“違和感”に気づきました。

この体験は、ER図だけ眺めていても絶対に得られないリアルな学びでした。

✅ 最後に:JOINは“構造に従う”

・外部キーは「繋がる」ためではなく、「自然に繋がる」ためにある

・JOINは「できるか」ではなく「読めるか」が大切

・構造が不自然なら、それは設計ミスのサイン

Discussion