この記事に関連するツール
ブラウザ上ですぐに試せます。記事の内容を確認しながら使うと、作業の流れをつかみやすくなります。
ER図は「描く」から「書く」へ
ER図(実体関連図)をドローツールで描くと、テーブルが増えるたびに線を繋ぎ直す作業が発生し、いつの間にか実際のスキーマと図がズレていきます。Mermaidの erDiagram を使えば、ER図をテキストで管理できます。コードと同じようにdiffが取れ、GitHubのREADMEやプルリクエスト、Notion、Zennにそのまま貼れば自動で描画されます。
この記事は、erDiagram の記法を一覧表と実例で引けるリファレンスです。最後に、既存のSQL(CREATE TABLE文)からこの記法を自動生成する方法も紹介します。
最小構成:まずこの3行から
erDiagram
USERS ||--o{ POSTS : "has"
これだけで「USERSとPOSTSが1対多(1人のユーザーが0個以上の投稿を持つ)」という図が描画されます。構文は次の形です。
<エンティティ1> <左の多重度><線><右の多重度> <エンティティ2> : "関係ラベル"
ポイントは、関係ラベル(: 以降)が省略できないこと。ラベルを表示したくない場合も : "" と空文字列を書く必要があります。ここが最初のつまずきどころです。
リレーション記号の早見表
erDiagram の多重度記号は「カラスの足(Crow’s Foot)記法」に対応しています。記号の向きは常にエンティティ側が外側です。
| 記号(左側) | 記号(右側) | 意味 |
|---|---|---|
|o | o| | 0または1(Zero or one) |
|| | || | ちょうど1(Exactly one) |
}o | o{ | 0以上(Zero or more) |
}| | |{ | 1以上(One or more) |
組み合わせの具体例で覚えるのが早いです。
| 書き方 | 読み方 |
|---|---|
A ||--o{ B | Aは1、Bは0個以上(最も使う1対多) |
A ||--|{ B | Aは1、Bは必ず1個以上 |
A |o--o| B | どちらも0または1(任意の1対1) |
A ||--|| B | 厳密な1対1 |
A }o--o{ B | 多対多(中間テーブルを挟む前の概念図に) |
実線と破線:識別関係と非識別関係
線の部分は2種類あります。
| 線 | 意味 | 使いどころ |
|---|---|---|
-- | 識別関係(実線) | 子が親のPKを自分のPKの一部として持つ(例: 注文明細) |
.. | 非識別関係(破線) | 子が親のPKを通常のFKとして持つだけ(例: 投稿と作成者) |
ORDERS ||--|{ ORDER_ITEMS : "contains" %% 識別関係(実線)
USERS ||..o{ POSTS : "writes" %% 非識別関係(破線)
%% はコメントです。チームの規約として「識別/非識別を使い分けるか、実線に統一するか」を最初に決めておくと図が安定します。
属性(カラム)の定義
エンティティ名の後ろに {} ブロックを付けると、カラムを表形式で表示できます。
erDiagram
USERS {
int id PK "自動採番"
varchar(255) email UK "ログインID"
varchar(100) name
datetime created_at
}
1行の構成は 型 カラム名 [キー] ["コメント"] です。
- キーは
PK/FK/UKの3種類。PK, FKのようにカンマ区切りで複数指定もできます(複合キーの中間テーブルで多用) - 型名には
varchar(255)のような括弧も使えます - コメントはダブルクォートで囲みます
実務サンプル:ECサイトの注文まわり
ここまでの記法を全部使った、コピペで動く完全サンプルです。
erDiagram
USERS ||--o{ ORDERS : "places"
ORDERS ||--|{ ORDER_ITEMS : "contains"
PRODUCTS ||--o{ ORDER_ITEMS : "included in"
USERS {
int id PK
varchar(255) email UK
varchar(100) name
datetime created_at
}
ORDERS {
int id PK
int user_id FK
varchar(20) status
datetime ordered_at
}
ORDER_ITEMS {
int order_id PK, FK
int product_id PK, FK
int quantity
decimal(10) unit_price
}
PRODUCTS {
int id PK
varchar(200) name
decimal(10) price
}
読みどころは ORDER_ITEMS です。注文と商品の多対多を、複合主キー(PK, FK の2本)を持つ中間テーブルに分解し、ORDERS ||--|{ ORDER_ITEMS(注文には必ず1件以上の明細がある)という業務ルールまで多重度で表現しています。
ハマりどころと回避策
- 関係ラベルは必須。省略すると構文エラーになる。非表示にしたければ
: "" - 日本語のエンティティ名は避けるのが無難。環境によって描画が不安定になるため、テーブル名は英語のまま、日本語は関係ラベルやコメントで補うのが安全
- 多対多(
}o--o{)は概念設計まで。物理設計に落とす段階で中間テーブルに分解する - GitHubで描画されないときは、コードブロックの言語指定が
```mermaidになっているかを確認
CREATE TABLE文から自動生成する
テーブルが10個を超えると、この記法を手書きするのも大変になってきます。既にDDL(CREATE TABLE文)があるなら、SQL to ER図 変換ツール に貼り付けるだけで、PK/FK・リレーションを解析したMermaid ER図を自動生成できます。

処理は完全にブラウザ内で完結するため、機密性の高いスキーマ情報が外部に送信されることはありません。生成したコードをこの記事の早見表を見ながら手直しする、という流れが最短です。ツールの詳しい使い方はSQL DDLからER図を自動生成する方法で解説しています。
よくある質問
1対多はどう書くのが正解ですか?
親 ||--o{ 子 が基本形です(親1件に対して子が0件以上)。「子が必ず1件以上ある」ことをスキーマ上のルールとして明示したい場合だけ ||--|{ を使います。迷ったら ||--o{ にしておくのが安全です。
リレーションの線だけ書いて、属性は省略してもいいですか?
問題ありません。erDiagram はリレーション行だけでもエンティティを自動生成して描画します。設計の初期段階ではリレーションだけの概念図を書き、固まってきたら {} ブロックで属性を追記する、という段階的な書き方が実務では使いやすいです。
MermaidのER図はどこで描画できますか?
GitHub(README・Issue・PR)、GitLab、Zenn、Notion、VS Code(拡張機能)、Obsidianなど、主要なMarkdown環境の多くが対応しています。```mermaid のコードブロックとして貼り付けるだけで描画されます。対応していない環境向けには、Mermaid Live EditorやツールでSVG/PNGに書き出す方法があります。
多対多のリレーションはそのまま実装できますか?
A }o--o{ B はあくまで概念レベルの表現で、リレーショナルデータベースには多対多を直接実装できません。物理設計では本文のECサンプルのように中間テーブル(複合主キー+FK2本)へ分解します。図の段階で分解まで書いておくと、実装時の手戻りがなくなります。