MermaidでER図を書く

# はじめに

ER図の作成方法について調べていたら、Mermaidに出会いました。
コードベースで図を書けて、GithubやNotion、Qiitaも対応しているようです。便利。

試しに以下のサイトの設計をもとに、MermaidでER図を書いてみました。
[SNS風Webサービスの設計を考える](https://www.techpit.jp/courses/11/curriculums/12/sections/103/parts/358)

# 公式ドキュメント
[Entity Relationship Diagrams](https://mermaid.js.org/syntax/entityRelationshipDiagram.html)

# ER図
### プレビュー

```mermaid
---
title: Sample App
---
erDiagram
    Users {
        int id PK "ユーザーを識別するID"
        string name UK "ユーザー名"
        string email UK "メールアドレス"
        string password "パスワード"
        string remember_token "カラムに値があればログイン状態を維持"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Articles {
        int id PK "記事を識別するID"
        string title "記事のタイトル"
        string body "記事の本文"
        string user_id FK　"記事を投稿したユーザーのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Likes {
        int id PK "いいねを識別するID"
        int user_id FK "いいねしたユーザーのID"
        int article_id FK "いいねされた記事のID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Tags {
        int id PK "タグを識別するID"
        int name UK "タグ名"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Article_Tag {
        int id PK "タグの紐付けを識別するID"
        string article_id FK "タグがつけられた記事のID"
        string tag_id FK "記事につけられたタグのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Follows {
        int id PK "フォーロー、被フォローの紐付けを識別するID"
        int follower_id FK "フォローしたユーザーのID"
        int followee_id FK "フォローされたユーザーのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Users ||--o{ Articles : makes
    Users ||--o{ Likes : sends
    Users ||--o{ Follows : choose
    Articles ||--o{ Likes : has
    Article_Tag ||--o{ Articles : associates
    Article_Tag ||--o{ Tags : associates
```

### コード

```
    Users {
        int id PK "ユーザーを識別するID"
        string name UK "ユーザー名"
        string email UK "メールアドレス"
        string password "パスワード"
        string remember_token "カラムに値があればログイン状態を維持"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Articles {
        int id PK "記事を識別するID"
        string title "記事のタイトル"
        string body "記事の本文"
        string user_id FK　"記事を投稿したユーザーのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Likes {
        int id PK "いいねを識別するID"
        int user_id FK "いいねしたユーザーのID"
        int article_id FK "いいねされた記事のID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Tags {
        int id PK "タグを識別するID"
        int name UK "タグ名"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Article_Tag {
        int id PK "タグの紐付けを識別するID"
        string article_id FK "タグがつけられた記事のID"
        string tag_id FK "記事につけられたタグのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Follows {
        int id PK "フォーロー、被フォローの紐付けを識別するID"
        int follower_id FK "フォローしたユーザーのID"
        int followee_id FK "フォローされたユーザーのID"
        datetime created_at "作成日時"
        datetime updated_at "更新日時"
    }
    Users ||--o{ Articles : makes
    Users ||--o{ Likes : sends
    Users ||--o{ Follows : choose
    Articles ||--o{ Likes : has
    Article_Tag ||--o{ Articles : associates
    Article_Tag ||--o{ Tags : associates
```

# 構文
### エンティティ
```
エンティティ {
    データ型 カラム名 制約 "説明"
       ・
　　　　　　　   　・
　　　　　　　   　・
    データ型 カラム名 制約 "説明"
}
```

### リレーション
```
<エンティティ1> <エンティティ同士の関連付け> <エンティティ2> : <関係性のラベル>
```

**エンティティ同士の関連付け**
```
<エンティティ1のカーディナリティ> <依存関係> <エンティティ2のカーディナリティ>
```
**カーディナリティ[^1]**
[^1]:カーディナリティ：もう一方のエンティティに対応するレコード数
<table>
  <thead>
    <tr style="text-algin:center">
      <th>カーディナリティ</th>
      <th>エンティティ1</th>
      <th>エンティティ2</th>
    </tr>
  </thead>
    <tr>
      <td>0か1</td>
      <td>|o</td>
      <td>o|</td>
    </tr>
    <tr>
      <td>1</td>
      <td>||</td>
      <td>||</td>
    </tr>
    <tr>
      <td>0以上</td>
      <td>}o</td>
      <td>o{</td>
    </tr>
    <tr>
      <td>1以上</td>
      <td>}|</td>
      <td>|{</td>
    </tr>
</table>

**依存関係[^2][^3]**
[^2]:依存リレーションシップ：外部キーにNULLを許さない
[^3]:非依存リレーションシップ：外部キーにNULLを許容する
<table>
  <thead>
    <tr style="text-algin:center">
      <th>依存リレーションシップ</th>
      <th>非依存リレーションシップ</th>
    </tr>
  </thead>
    <tr>
      <td>--(直線)</td>
      <td>..(破線)</td>
    </tr>
</table>

# おわりに
コードで書けるので再利用しやすいのと、レイアウトについて考えなくて良いのがメリットだと思います。
レイアウトも多少はいじれるようですが、レイアウトにこだわりたい時には他のツールを使った方が良い気がしました。

個人的にはNotionで使える点が推しポイントです。

シーケンス図やフロー図、クラス図など様々な図を描画できるのでみなさんもぜひ。