ER図の作成
概要
- 日程: Day 7 / セッション 3
- 時間: 11:10-12:40(90分)
- 形式: 実習
- ゴール: テーブル間のリレーション(1対1・1対多・多対多)を明示したER図を時間内に作成でき、多対多は中間テーブルで解決できる
- 学習形式: ハンズオン実習(AIサポートあり)
導入(5分)
前セッションでテーブル定義書ができました。各テーブルの「中身」は分かりました。
ところで、テーブルどうしはどう繋がっているでしょうか?
問いかけ:会員と予約の関係を一言で言うと?
→「会員1人が複数の予約をする」、つまり 1対多 の関係です。
このようなテーブル間の関係を1枚の図にしたものが ER図(Entity-Relationship Diagram) です。テーブル定義書だけでは見えない全体の地形を見える化します。
本編(25分)
1. ER図の基本
ER図は、エンティティ(テーブル)どうしの関係を表す図です。1970年にチェン(Peter Chen)が提案した記法が始まりです。
構成要素
| 要素 | 意味 |
|---|---|
| エンティティ(Entity) | テーブル(≒情報モデル) |
| 属性(Attribute) | カラム |
| リレーション(Relationship) | テーブル間の関係 |
| カーディナリティ(Cardinality) | 関係の多重度(1対1, 1対多, 多対多) |
Mermaid記法での書き方
本研修では Mermaid の erDiagram 記法を使います。
カーディナリティ表記(Mermaid)
| 記号 | 意味 |
|---|---|
|| |
1(必ず1つ) |
o| |
0または1 |
|{ |
1以上 |
o{ |
0以上 |
例:MEMBERS ||--o{ RESERVATIONS は「会員は0以上の予約を持つ」「予約は必ず1人の会員に属する」を意味します。
2. 1対多の典型例
最もよく出るのが 1対多 の関係です。
たとえば「会員」と「予約」:
- 1人の会員は複数の予約を持てる
- 1つの予約は必ず1人の会員に属する
外部キーは「多」側のテーブルに置く。予約テーブルが member_id を持ちます。
ここがポイント
- 「多」側が外部キーを持つ、これが1対多の基本ルール
- カーディナリティの「0」(任意)と「1」(必須)の使い分けに注意
- 会員は予約を1件も持たなくてもよい→「o{」、予約は必ず会員を持つ→「||」
3. 多対多と中間テーブル
DBMSは多対多をそのままでは表現できません。中間テーブル で1対多に分解します。
多対多の例:商品とタグ
- 1つの商品は複数のタグを持つ
- 1つのタグは複数の商品に付く
これを中間テーブル product_tags で解決します。
中間テーブル product_tags は2つの外部キーの組み合わせを 複合主キー にします。
中間テーブルが「ただの中継」を超えるとき
中間テーブルに追加情報を持たせることもあります。
たとえば「会員」と「イベント」の多対多に「参加日時」「出欠ステータス」を持たせるなら、中間テーブル event_participants は意味のあるエンティティになります。
4. 1対1の使いどころ
1対1は比較的少ないですが、次のような場面で使います。
- 機密情報を別テーブルに分離(
membersとmember_secrets) - 巨大なテキストやバイナリを別テーブルに分離(
articlesとarticle_bodies) - サブタイプ(
usersとusers_admin_extras)
コラム:ER図記法の流派
ER図には複数の記法があります。Chen記法(菱形で関係を描く古典派)、IE記法(Information Engineering、烏の足のような線で多を表現)、IDEF1X(米国規格、丸と直線で多重度を表現)など。本研修の Mermaid erDiagram は IE記法に近い形式です。世の中の設計書では IE記法が最も多く見られますが、現場ごとに使う記法は違います。「この記法ではこの線が何を意味するか」を読めるようになれば、どの流派でも対応できます。
5. テーブル定義書とER図のクロスチェック
ER図を描いたら、必ずテーブル定義書とつき合わせます。
| チェック観点 | 例 |
|---|---|
| ER図のエンティティ=テーブル定義書のテーブルすべて | 抜けているテーブルが無いか |
| ER図に登場する外部キー=テーブル定義書のFK列 | 列が定義されているか |
| 多対多のリレーション | 中間テーブルが定義書にあるか |
| カーディナリティの NULL 許容 | テーブル定義書の NULL 可否と一致するか |
💬 AIに聞いてみよう
- 「私たちのテーブル定義書(貼り付け)からER図のたたき台を Mermaid erDiagram で書いて」
- 「私たちのER図に多対多はある? 中間テーブルは正しく分解されている?」
- 「会員と『お気に入り商品』の関係はどう設計するべき? 1対多か多対多か」
- 「中間テーブルに persist する追加情報の例を3つ挙げて」
実習・演習(50分)
課題
自チームのテーブル定義書(またはファイル設計書)を入力として、ER図を作成します。
進め方(推奨タイムテーブル)
| 時間 | 作業 |
|---|---|
| 5分 | テーブル定義書からエンティティを列挙 |
| 10分 | テーブル間の関係(1対1, 1対多, 多対多)を洗い出す |
| 10分 | 多対多は中間テーブルに分解 |
| 10分 | Mermaid erDiagram で清書 |
| 10分 | AI に ER図をレビューしてもらう |
| 5分 | テーブル定義書と相互チェック(不整合があれば双方を修正) |
成果物
- ER図(Mermaid erDiagram 形式、または手描き/作図ツール)
- ER図とテーブル定義書の整合性チェックリスト
ヒント
リレーションが見つからないとき
- ペルソナのカスタマージャーニーマップに戻り、「Aを操作したとき同時にBに影響するか」を考える
- 機能一覧の各機能で「どのテーブルとどのテーブルが同時に必要か」を見る
- 「○○の一覧」という画面が存在するとき、必ず1対多の関係がある
多対多の見つけ方
「お互いに複数を持ち合う」関係が多対多です。例:
- 会員 と お気に入り商品
- 記事 と タグ
- 学生 と 講義
まとめ(5分)
今日のセッションの要点を3つに絞ります。
- ER図はテーブル間の 全体の地形 を見える化する
- 多対多は中間テーブルで1対多に分解。複合主キーを使う
- ER図とテーブル定義書は 必ずクロスチェック。どちらかを直したらもう一方も直す
明日(Day 8)は、機能とテーブルの対応をマトリクスで見る CRUD図 と、機能の中身を定義する 機能設計書 を作ります。
🔄 振り返りチェック
- 自チームのER図が完成している
- 1対多のリレーションを2つ以上説明できる
- 多対多があれば中間テーブルに分解されている
- ER図とテーブル定義書の不整合が0
- AI にレビューを依頼し、指摘を1つ以上反映した
補足資料
- 前セッション資料:
Day7_Session02_正規化とテーブル定義書の作成.md - 自チームのテーブル定義書(前セッション成果物)
- 参考: Mermaid erDiagram 公式ドキュメント
学習ガイド
想定される質問と回答例
| 質問 | ヒント |
|---|---|
| 1対1の関係は本当に必要?1つのテーブルにまとめれば? | パスワードハッシュなど秘匿性が高い・更新頻度が違う・サイズが大きい場合に分離する価値がある |
| 中間テーブルの名前はどう付ける? | 親1_親2 の単純結合か(product_tags)、業務的な意味名(registrations)。意味があるなら後者を選ぶ |
| 1対多と多対多を見分けるコツは? | 両側から「複数持つ?」を問う。両方YESなら多対多 |
| 自己参照リレーションって何? | 同じテーブルへの参照(例:従業員テーブルの上司ID)。組織図やコメントの返信などで使う |
| サークル状のリレーションはダメ? | 必ずしもダメではないが、削除順序の悩みが増える。1つの方向で十分なら一方向にする |
つまずきやすいポイント
| つまずきポイント | ヒント |
|---|---|
| 外部キーの方向が逆になる | 「多側がFKを持つ」と覚える。会員1:予約多なら予約に member_id |
| 多対多に気づかず1対多で描く | 後で実装時に困る。「同じ商品に複数のタグ」「同じタグに複数の商品」両方YESかをチェック |
| カーディナリティの 0 と 1 の区別 | NULL を許せば 0、必須なら 1。テーブル定義書の NOT NULL と一致させる |
| ER図と定義書がズレる | 「定義書を正、図はビュー」と決め、必ず両方を更新する習慣をつける |
| Mermaid 記法のエラー | エンティティ名は英大文字スネークが安全。日本語ラベルはダブルクォートで囲む |