📖 テーマ設定
🔊 音声設定
1.2
1.0
1.0
▶️ 再生コントロール
🎵 BGM設定
0.3
🔔 効果音設定
0.3

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 記法を使います。

erDiagram MEMBERS ||--o{ RESERVATIONS : "予約する" SHOPS ||--o{ RESERVATIONS : "予約される" MEMBERS { int id PK string name string email } RESERVATIONS { int id PK int member_id FK int shop_id FK datetime reserved_at } SHOPS { int id PK string name string address }

カーディナリティ表記(Mermaid)

記号 意味
|| 1(必ず1つ)
o| 0または1
|{ 1以上
o{ 0以上

例:MEMBERS ||--o{ RESERVATIONS は「会員は0以上の予約を持つ」「予約は必ず1人の会員に属する」を意味します。

2. 1対多の典型例

最もよく出るのが 1対多 の関係です。

たとえば「会員」と「予約」:

  • 1人の会員は複数の予約を持てる
  • 1つの予約は必ず1人の会員に属する
erDiagram MEMBERS ||--o{ RESERVATIONS : "持つ" MEMBERS { int id PK string name } RESERVATIONS { int id PK int member_id FK datetime reserved_at }

外部キーは「多」側のテーブルに置く。予約テーブルが member_id を持ちます。

ここがポイント

  • 「多」側が外部キーを持つ、これが1対多の基本ルール
  • カーディナリティの「0」(任意)と「1」(必須)の使い分けに注意
  • 会員は予約を1件も持たなくてもよい→「o{」、予約は必ず会員を持つ→「||」

3. 多対多と中間テーブル

DBMSは多対多をそのままでは表現できません。中間テーブル で1対多に分解します。

多対多の例:商品とタグ

  • 1つの商品は複数のタグを持つ
  • 1つのタグは複数の商品に付く

これを中間テーブル product_tags で解決します。

erDiagram PRODUCTS ||--o{ PRODUCT_TAGS : "持つ" TAGS ||--o{ PRODUCT_TAGS : "付く" PRODUCTS { int id PK string name int price } TAGS { int id PK string name } PRODUCT_TAGS { int product_id PK_FK int tag_id PK_FK }

中間テーブル product_tags は2つの外部キーの組み合わせを 複合主キー にします。

中間テーブルが「ただの中継」を超えるとき

中間テーブルに追加情報を持たせることもあります。

たとえば「会員」と「イベント」の多対多に「参加日時」「出欠ステータス」を持たせるなら、中間テーブル event_participants は意味のあるエンティティになります。

erDiagram MEMBERS ||--o{ EVENT_PARTICIPANTS : "参加" EVENTS ||--o{ EVENT_PARTICIPANTS : "開催" EVENT_PARTICIPANTS { int member_id PK_FK int event_id PK_FK datetime applied_at string status }

4. 1対1の使いどころ

1対1は比較的少ないですが、次のような場面で使います。

  • 機密情報を別テーブルに分離(membersmember_secrets
  • 巨大なテキストやバイナリを別テーブルに分離(articlesarticle_bodies
  • サブタイプ(usersusers_admin_extras
erDiagram MEMBERS ||--|| MEMBER_SECRETS : "保有" MEMBERS { int id PK string name } MEMBER_SECRETS { int member_id PK_FK string password_hash string two_factor_secret }

コラム: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つに絞ります。

  1. ER図はテーブル間の 全体の地形 を見える化する
  2. 多対多は中間テーブルで1対多に分解。複合主キーを使う
  3. 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 記法のエラー エンティティ名は英大文字スネークが安全。日本語ラベルはダブルクォートで囲む
読み上げを開始します...

AIに質問する