ER図の読み方・書き方

このレッスンで分かること

  • ER 図はエンティティ (四角)・属性 (列)・リレーションシップ (線) の 3 要素で構成
  • ||--o{ は「1 対 0 以上」、||--|{ は「1 対 1 以上」、必須/任意で意味が変わる
  • mermaid の erDiagram で素早く ER 図を書ける

ER図の読み方・書き方 とは

データベース設計の基本となるER図の読み方と書き方を解説します。本レッスンでは、ER図の読み方・書き方 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

ER図 (Entity-Relationship Diagram) は、データ設計のいわば「共通言語」です。チームで設計をレビューするとき、口頭で「ユーザと注文が 1対多 で…」と説明するより、ER 図を見せた方が大きくに速く正確に伝わります。エンジニアだけでなく、PM やデザイナーとの会話にも使えます。さらに、ER 図を書く過程そのものが、業務理解を深める手段になります。エンティティが思い浮かばない・関連が描けない、というのは「業務をまだ理解していないサイン」です。逆に、ER 図がスラスラ書ければ、CREATE TABLE は機械的に書き起こせます。本レッスンでは、ER 図の基本要素と読み書きの作法、そして mermaid 記法での書き方を押さえます。

ER 図は「データ設計の地図」です。文章で長々と説明するより 1 枚の図を見せたほうが、チーム全員が同じ理解にたどり着けます。

ER 図の構成要素

ER 図には大きく 3 つの要素があります。エンティティ は四角形で表す「物事」(テーブルに相当)。属性 はエンティティが持つ性質(列に相当)。リレーションシップ はエンティティ同士の関連を表す線です。線の端には「カラスの足」(crow's foot) と呼ばれる記号を付けて、多重度(1 対 1、1対多多対多)を表します。

記号意味
二重線 (`
丸+棒 (`o`)
カラスの足 (}o)0 以上 (任意・多)
カラスの足+棒 (`}`)

ステップごとの動作

mermaid 記法 (erDiagram) では、シンプルな構文で ER 図を書けます。||--o{ のような記号が カーディナリティ を表します。左側がエンティティ A、右側がエンティティ B として、A 側「1 個」B 側「0 個以上」のように読みます。

diagram (will load when visible)

mermaid の主要記号は次のとおりです。

記号意味
||--o{1 対 0 以上ユーザは注文を持たないこともある
||--|{1 対 1 以上注文は必ず 1 つ以上の明細を持つ
||--||1 対 1ユーザはプロフィール 1 件と紐づく
}o--o{多対多学生と授業 (中間テーブル必須)

この図は「ユーザは 0 件以上の注文を出す」「注文は 1 件以上の注文明細を含む」「商品は 0 件以上の注文明細に現れる」という業務ルールを表します。PK主キーFK外部キー の注釈です。

代表例

まず、典型的な EC サイトの ER 図を、テーブル定義に落とします。ER 図で線を引いた箇所が、物理的には外部キー列になります。

SQL クエリ

CREATE TABLE users ( id INT PRIMARY KEY, name TEXT NOT NULL, email TEXT NOT NULL ); CREATE TABLE orders ( id INT PRIMARY KEY, user_id INT NOT NULL, ordered_at TIMESTAMP NOT NULL ); CREATE TABLE order_items ( id INT PRIMARY KEY, order_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL );

次に、ER 図から読み取った関係を SQL で確認します。たとえば「各ユーザの注文件数」を出す場合、ER 図の USERS ||--o{ ORDERS の関係をそのまま JOIN として書きます。

SQL クエリ

SELECT u.name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id, u.name ORDER BY u.id;

ER 図を見れば、u.id = o.user_id の結合条件は自動的に読み取れます。これが「ER 図がそのまま SQL の設計図になる」と言われる所以です。

よくある落とし穴

カーディナリティの「必須/任意」を曖昧にしない。||--o{ (1 対 0 以上) と ||--|{ (1 対 1 以上) は似ていますが、業務上の意味が違います。注文に必ず明細があるなら ||--|{、空の注文も許すなら ||--o{。この差が後の NOT NULL 制約に直結します。

ER 図は完璧を目指さない。最初は手書きの汚い図でも構いません。チーム内で「これで認識が揃ったか」を確認することが目的です。完璧な見た目より、議論を呼ぶスピード感を優先しましょう。

ER 図を書く 4 ステップ

実務でゼロから ER 図を書くときは、おおよそ次の順序で進めると迷いません。1. エンティティ列挙 業務に登場する名詞をすべて書き出す。2. 主キー決定 各エンティティを一意に識別する 主キー を選ぶ。3. 関連線を引く どのエンティティとどのエンティティがどの多重度で繋がるかを決める。4. 属性追加 残りの列を埋める。順序を逆にする(先に列を増やす)と、後から関連の見直しが膨大な手戻りになります。

この章のポイント

ここまでの要点 ER 図は 3 要素 (エンティティ・属性・関連)、カラスの足記法で多重度を表現。書く順序は「エンティティ → 主キー → 関連 → 属性」、必須 (|) と任意 (o) の違いに注意。

まとめ

  • ER 図はエンティティ・属性・リレーションシップの 3 要素で構成される
  • 線の両端の記号でカーディナリティ(1 対 1、1 対多、多対多)と必須/任意を表す
  • mermaid の erDiagram で素早く ER 図を書ける
  • ER 図がそのまま SQL(外部キー・JOIN)の設計図になる
  • ゼロから書くときはエンティティ → 主キー → 関連 → 属性の順で進めると手戻りが少ない

次のレッスン

次は エンティティと属性 です。データベースの基本要素、エンティティと属性をSQLで操作します。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. ER 図 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. ER 図 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

テーブル構造

schema.sql

CREATE TABLE users ( id INT PRIMARY KEY, name TEXT NOT NULL, email TEXT NOT NULL ); CREATE TABLE orders ( id INT PRIMARY KEY, user_id INT NOT NULL, ordered_at TIMESTAMP NOT NULL ); CREATE TABLE order_items ( id INT PRIMARY KEY, order_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL ); CREATE TABLE products ( id INT PRIMARY KEY, name TEXT NOT NULL, price INT NOT NULL ); INSERT INTO users (id, name, email) VALUES (1, '田中', 'tanaka@example.com'), (2, '鈴木', 'suzuki@example.com'), (3, '佐藤', 'sato@example.com'); INSERT INTO products (id, name, price) VALUES (1, 'りんご', 200), (2, 'バナナ', 150), (3, 'みかん', 100); INSERT INTO orders (id, user_id, ordered_at) VALUES (1, 1, '2026-01-10 10:00:00'), (2, 1, '2026-01-15 14:00:00'), (3, 2, '2026-01-20 09:00:00'); INSERT INTO order_items (id, order_id, product_id, quantity) VALUES (1, 1, 1, 2), (2, 1, 2, 3), (3, 2, 3, 5), (4, 3, 1, 1), (5, 3, 2, 2);

期待される出力

nametotal_amount
田中1350
鈴木500

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...