Works
Blog Recruit Contact 無料でAI診断する
Mermaid
calendar_today
[Mermaid入門 Vol.3] 山下 太郎 山下 太郎

Mermaid入門 第3回:状態遷移図とER図 ― システムの「振る舞い」と「関係」を描く

システムの「振る舞い」と「関係」を図で描く力は、AI時代の設計の共通言語になります。Mermaidで状態遷移図(stateDiagram-v2)とER図(erDiagram)を実務的に描く方法と、モデリング思考を鍛える視点を解説します。

Mermaid入門 第3回:状態遷移図とER図 ― システムの「振る舞い」と「関係」を描く

第1回で Mermaid の基礎と環境構築を、第2回でフローチャート・シーケンス図・クラス図・ガントチャートの応用を扱ってから、ちょうど一年あまりが経ちました。その間、Mermaid は静かに、しかし確実に進化しています。v11 系で描画エンジンそのものが刷新され、新しいダイアグラム(Architecture、Packet、Block、Timeline、Kanban、Radar、Treemap…)が次々に追加され、見た目も classic に加えて handDrawn と neo という新しい「ルック」が選べるようになりました。

同時にもうひとつの地殻変動が起きています。LLM が Mermaid を書くようになったことです。ChatGPT、Claude、Gemini のいずれも、指示すれば Mermaid コードを返してくれる。そして人間はそれを検証し、整え、公開する。テキスト記法であるがゆえに、Mermaid は AI との相性が非常によく、いまや「AI と人間が共同で図を描く」道具に変わりつつあります。

この一年間のアップデートを一気に紹介しようとすると分量が膨らむため、本シリーズは発展編として三部構成でお届けします。今回(第3回)は、第2回の予告で残した宿題である 状態遷移図と ER 図 という古典的でありながら強力な二つの道具を、しっかり深掘りします。

1. 状態遷移図 ― システムの「振る舞い」をモデル化する

フローチャートが「処理の流れ」を描くのに対し、状態遷移図(State Diagram)は システムが今どういう状態にあり、何が起きると別の状態に遷移するか を描きます。AIエージェント、決済システム、ワークフロー管理、画面遷移、IoTデバイス。どれも「状態」と「遷移のきっかけ」で語れるシステムは、状態遷移図が最も雄弁に説明してくれます。

Mermaid では状態遷移図に stateDiagramstateDiagram-v2 の二つの記法が用意されています。公式ドキュメントは stateDiagram-v2 を中心に案内されており、新規に書くなら stateDiagram-v2 を採用するのが無難です。

1-1. 基本:開始・終了・遷移

最もシンプルな例から見ていきます。[*] が開始点と終了点を兼ねる特別な記号です。

Mermaid
stateDiagram-v2
    [*] --> 待機
    待機 --> 受信 : リクエスト到着
    受信 --> 処理中 : 検証OK
    受信 --> エラー : 検証NG
    処理中 --> 応答
    エラー --> 待機 : リトライ
    応答 --> [*]
stateDiagram-v2 [*] --> 待機 待機 --> 受信 : リクエスト到着 受信 --> 処理中 : 検証OK 受信 --> エラー : 検証NG 処理中 --> 応答 エラー --> 待機 : リトライ 応答 --> [*]

矢印の右に : で区切って書くラベルが、遷移のきっかけ(トリガー)になります。状態は名詞、遷移ラベルはイベント・条件・アクションを表す短い句にするのがコツです。

1-2. コンポジット状態 ― 状態の中に状態を入れる

状態遷移図が真価を発揮するのは、状態を入れ子にできるところです。外側から見ると「実行中」という単一の状態なのに、その内側には独自のミニ状態機械が走っている、という構造を state 実行中 { ... } という記法で表現できます。

AIエージェントのライフサイクルを例にしましょう。外側は「待機・実行中・終了」の3状態ですが、「実行中」の中には「推論・ツール呼び出し・応答生成」という内部フェーズが存在します。

Mermaid
stateDiagram-v2
    [*] --> 待機
    待機 --> 実行中 : タスク受領
    
    state 実行中 {
        [*] --> 推論
        推論 --> ツール呼出 : 外部情報が必要
        ツール呼出 --> 推論 : 結果を戻す
        推論 --> 応答生成 : 十分な情報
        応答生成 --> [*]
    }
    
    実行中 --> 待機 : 完了
    実行中 --> エラー : 例外
    エラー --> 待機 : リセット
    待機 --> [*] : シャットダウン
stateDiagram-v2 [*] --> 待機 待機 --> 実行中 : タスク受領 state 実行中 { [*] --> 推論 推論 --> ツール呼出 : 外部情報が必要 ツール呼出 --> 推論 : 結果を戻す 推論 --> 応答生成 : 十分な情報 応答生成 --> [*] } 実行中 --> 待機 : 完了 実行中 --> エラー : 例外 エラー --> 待機 : リセット 待機 --> [*] : シャットダウン

コンポジット状態は、状態数が10を超えそうなときの救済策にもなります。図が散らかってきたら、関連する状態を一つの箱に畳み込む。これはソースコードで関数を切

り出すのと同じ発想で、複雑さを抽象化の層で分ける技術です。

1-3. choice と fork/join ― 分岐と並列

もう少し実務的な道具を二つ紹介します。<<choice>> は条件による分岐、<<fork>>/<<join>> は並列処理を表します。

Mermaid
stateDiagram-v2
    state 判定 <<choice>>
    [*] --> 入力受取
    入力受取 --> 判定
    判定 --> 承認 : スコア >= 閾値
    判定 --> 却下 : スコア < 閾値
    承認 --> [*]
    却下 --> [*]
stateDiagram-v2 state 判定 <<choice>> [*] --> 入力受取 入力受取 --> 判定 判定 --> 承認 : スコア >= 閾値 判定 --> 却下 : スコア < 閾値 承認 --> [*] 却下 --> [*]

並列処理(fork/join)は、一つの起点から複数の処理を同時に走らせ、すべての完了後に合流する、というパターンを表します。

Mermaid
stateDiagram-v2
    state 並列処理 <<fork>>
    state 合流 <<join>>
    [*] --> 並列処理
    並列処理 --> ログ記録
    並列処理 --> 通知送信
    並列処理 --> キャッシュ更新
    ログ記録 --> 合流
    通知送信 --> 合流
    キャッシュ更新 --> 合流
    合流 --> [*]
stateDiagram-v2 state 並列処理 <<fork>> state 合流 <<join>> [*] --> 並列処理 並列処理 --> ログ記録 並列処理 --> 通知送信 並列処理 --> キャッシュ更新 ログ記録 --> 合流 通知送信 --> 合流 キャッシュ更新 --> 合流 合流 --> [*]

同じ図の中に <<choice>><<fork>> を混在させることもできます。マイクロサービスの同期処理(choice)と非同期イベントファンアウト(fork)を一枚に収めるときに便利です。

1-4. 並行領域 ― 同時に動く複数の状態機械

コンポジット状態の中で -- を使うと、独立に動く複数の並行領域が作れます。CPU とメモリと I/O がそれぞれ独自の状態を持ちつつ同時に動いている、というような状況を一枚の図で表せます。

Mermaid
stateDiagram-v2
    [*] --> 稼働中
    
    state 稼働中 {
        [*] --> CPU_Idle
        CPU_Idle --> CPU_Busy : タスク到着
        CPU_Busy --> CPU_Idle : 完了
        --
        [*] --> Mem_Low
        Mem_Low --> Mem_High : 割当
        Mem_High --> Mem_Low : 解放
        --
        [*] --> IO_待機
        IO_待機 --> IO_送信 : 要求
        IO_送信 --> IO_待機 : 応答
    }
    
    稼働中 --> [*] : シャットダウン
stateDiagram-v2 [*] --> 稼働中 state 稼働中 { [*] --> CPU_Idle CPU_Idle --> CPU_Busy : タスク到着 CPU_Busy --> CPU_Idle : 完了 -- [*] --> Mem_Low Mem_Low --> Mem_High : 割当 Mem_High --> Mem_Low : 解放 -- [*] --> IO_待機 IO_待機 --> IO_送信 : 要求 IO_送信 --> IO_待機 : 応答 } 稼働中 --> [*] : シャットダウン

1-5. さらに踏み込むなら:notes、direction、classDef

ここまでで実務の大半はカバーできますが、stateDiagram-v2 にはまだ道具があります。状態に注釈を付ける note right of / note left of、図全体の流れる方向を指定する direction LR(左→右)や direction TB(上→下)、状態ごとにスタイルを割り当てる classDef など。長いレビューや発表資料で「この状態だけ強調したい」「読者の視線の流れを変えたい」というときに使える脇役たちです。公式ドキュメントの State Diagram リファレンスが網羅的なので、必要になった段階で参照してみてください。

1-6. 状態遷移図を書くときの三原則

経験則を三つにまとめます。

状態は名詞、遷移は動詞。 「処理する」は状態ではなく、「処理中」が状態です。遷移ラベルは「完了」ではなく「処理完了」のように、何が起きたかが一目で分かる動詞句にします。

すべての状態に出口を用意する。 入口だけあって出口のない状態は、書き手の設計漏れを示しています。意図的なデッドエンド([*] で終端)なのか、単に書き忘れているのか、はっきりさせる。

10を超えたらコンポジットで畳む。 平面に10個以上の状態が並ぶ図は読まれません。関連する状態をまとめて内側に隠し、外側は抽象化した名前で呼びます。

2. ER図 ― データの「関係」を描く

ER図(Entity-Relationship Diagram)は、データベーススキーマやデータモデルを可視化する古典的な道具です。Mermaid の ER 図はカラス足記法(crow's foot notation)を採用しており、多重度(カーディナリティ)が直感的に読めます。

2-1. 基本構文

ECサイトの最小構成(ユーザー・注文・注文明細・商品)を例に見ていきます。

Mermaid
erDiagram
    USER ||--o{ ORDER : places
    ORDER ||--|{ ORDER_ITEM : contains
    PRODUCT ||--o{ ORDER_ITEM : references
    
    USER {
        string id PK
        string email UK
        string name
        datetime created_at
    }
    ORDER {
        string id PK
        string user_id FK
        datetime ordered_at
        string status
    }
    PRODUCT {
        string id PK
        string name
        decimal price
        int stock
    }
    ORDER_ITEM {
        string id PK
        string order_id FK
        string product_id FK
        int quantity
        decimal unit_price
    }
erDiagram USER ||--o{ ORDER : places ORDER ||--|{ ORDER_ITEM : contains PRODUCT ||--o{ ORDER_ITEM : references USER { string id PK string email UK string name datetime created_at } ORDER { string id PK string user_id FK datetime ordered_at string status } PRODUCT { string id PK string name decimal price int stock } ORDER_ITEM { string id PK string order_id FK string product_id FK int quantity decimal unit_price }

エンティティ(テーブル)を ENTITY_NAME { ... } で宣言し、属性を 型 名前 制約 の形で並べます。PK は主キー、FK は外部キー、UK はユニークキー。これらはカラム名の後に付記して、キー制約を明示します。

2-2. カーディナリティ記号の読み方

ER図を書くうえで最も大事なのは、リレーション線の両端に付く記号です。左右それぞれの端に、以下の4種類のマークを組み合わせて使います。

記号意味
`o / o`ゼロまたは1
``ちょうど1
}o / o{ゼロ以上
`} / {`1以上

つまり USER ||--o{ ORDER は「1人のUSERが0以上のORDERを持つ」=一対多の関係。ORDER ||--|{ ORDER_ITEM は「1つのORDERは1つ以上のORDER_ITEMを持つ」=空のORDERは許されない、という意味になります。

書いた図が自分の設計意図と一致しているかは、必ず日本語で読み上げて確認してください。「ユーザー1人につき注文は0以上、注文1件につき明細は1つ以上、商品は複数の明細から参照される」——そう声に出して破綻がなければ、関係線は正しく引けています。

2-3. identifying / non-identifying ― 実線と破線の違い

カーディナリティ記号と並んでもう一つ押さえておきたいのが、リレーション線そのものの種類です。Mermaid の ER 図では、ハイフン -- で結ぶと実線(identifying relationship)、ドット .. を挟むと破線(non-identifying relationship)になります。

この区別は「関係する相手がいなくても、そのエンティティが単独で存在できるか」を表しています。

Mermaid
erDiagram
    PERSON }|..|{ CAR : "driver"
    CAR ||--o{ NAMED_DRIVER : allows
    PERSON ||--o{ NAMED_DRIVER : is
erDiagram PERSON }|..|{ CAR : "driver" CAR ||--o{ NAMED_DRIVER : allows PERSON ||--o{ NAMED_DRIVER : is

PERSON }|..|{ CAR(破線)は「人と車は相互に存在しうる――車がなくても人は存在するし、人がいなくても車は存在する」ことを示します。一方 CAR ||--o{ NAMED_DRIVER(実線)は「NAMED_DRIVER は CAR と PERSON の両方がなければ存在できない」という、存在依存を伴う関係を示します。

ざっくりした使い分けとしては、中間テーブル(多対多の解決)や親子の強い所有関係は実線、独立して存在できるエンティティ同士の関連付けは破線、と覚えておけば実務の大半は通ります。

2-4. 実務で効く Tips

データ型は実装DBに寄せる。 string だけで通すこともできますが、varchar(255)textdecimal(10,2)timestamp のように、ターゲットのDBエンジンに合わせた型名を書いておくと、そのまま DDL に落とし込むときの手戻りが減ります(Mermaid 側では型名に暗黙の制約はなく、英字で始まる任意の文字列が使えます)。

属性にコメントを添える。 カラム名のあとにダブルクォートでコメントを書けます。user_id FK "注文者のID" のように書くと、テーブルの意図が読み手に伝わりやすくなります。ドメイン固有の略語を使うテーブルほど、この一手間が効きます。

外部キーは関係線の向きで表現する。 ER図で FK を記号と文字の両方で示すとノイズが増えます。リレーション線がカーディナリティを示しているので、FK 表記は存在の確認程度に留め、関係そのものは線で読ませるのが綺麗です。

エンティティ名は単数形で揃える。 公式ドキュメントも「エンティティ名は単数名詞で命名する」と明記しています。大文字表記は必須ではありませんが慣例として広く使われているため、チーム規約として大文字統一を決めておくと、レビュー時の表記ゆれによるストレスが減ります。

まとめ

状態遷移図と ER 図は、どちらも20年以上前から使われてきた古典的な図解です。しかし古典だからこそ、システムの本質を抜き出す力が強い。「このシステムは何状態あり、何で遷移するのか」「このデータは何と何が、どの多重度でつながっているのか」——この二つに答えられれば、たいていの設計議論は前に進みます。

Mermaid の stateDiagram-v2erDiagram は、この二つの古典を最も手軽に書き出せる現代のツールです。記法はシンプルですが、コンポジット状態・並行領域・カラス足記法・identifying/non-identifying・キー制約など、踏み込んで使える機能を備えています。

次回の 第4回 では、この一年で Mermaid に加わった新しいダイアグラム群——Architecture、Timeline、Kanban、Radar、Treemap、Packet、Block——と、v11 で刷新された Shape・Look・Layout を、まとめて棚卸しします。古典の強みを押さえたうえで、新しい表現力を自分の武器に加えていきましょう。

参考情報
山下 太郎

山下 太郎

代表取締役 / CEO

2000年、Webデザイナーとしてこの世界に飛び込み、フリーランスを経て2007年に株式会社アンタイプを創業。AI時代の到来とともに、効率だけを追うAI活用に違和感を覚えながら、それでも最前線でツールを使い続ける。企業のWebとコミュニケーションを設計する仕事を通じて、「人間らしさとは何か」を問い直す視点を発信し続けている。

View Profile arrow_outward

Categories

Related

あわせて読みたい

Mermaid入門 第2回:実践編 - 図解で伝えるAI概念
Mermaid
Mermaid

Mermaid入門 第2回:実践編 - 図解で伝えるAI概念

MermaidでAI技術を効果的に図解する方法を解説。Model Context Protocol(MCP)や3Cスキルといった最新AI概念を例に、フローチャート、シーケンス図、クラス図などの実践的なコード例を紹介。コピペで使えるサンプル付き。