「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_id
、channel_id
、episode_id
、start_time、views
などが集約されている
これを起点にJOINすれば、ユーザーが知りたい「いつ・何が・どこで」すべて取得できます。
💡 設計して、書いて、初めて気づくこと
SQLを書いてみてはじめて、
「ここに外部キーがないとJOINできない」
「このJOINは構造が逆流していて読みにくい」
といった“違和感”に気づきました。
この体験は、ER図だけ眺めていても絶対に得られないリアルな学びでした。
✅ 最後に:JOINは“構造に従う”
・外部キーは「繋がる」ためではなく、「自然に繋がる」ためにある
・JOINは「できるか」ではなく「読めるか」が大切
・構造が不自然なら、それは設計ミスのサイン
Discussion