14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NTTコムウェアAdvent Calendar 2024

Day 7

Mermaid.jsで快適な作図をお届け

Last updated at Posted at 2024-12-04

この記事はNTTコムウェア Advent Calendar 2024 7日目の記事です。

こんにちは、NTTコムウェアの濱崎です。

オープンソーステクノロジセンタ なる組織に所属しており、
普段はPostgreSQLに関するノウハウ展開、支援に従事しています。
が、今回はPostgreSQLが主題ではありません。

はじめに

いきなりですが、下の図を見てください。

frustrating-work.png

何か感じましたか?私はイライラしました。

理由はコレです。
frustrating-work2.png

A型の人なら共感してもらえると思います。
誰もが1度は経験したことのある図形配置の煩わしさ。

シンプルな図形や配置なら多少の調整でよいですが、
何か情報を図示するダイアグラムの場合、煩雑になり、微調整で時間が溶けることも...

そこで使えるのがMermaid です。

Mermaidとは

JavaScript ベースのダイアグラム作成およびチャート作成ツールです。

MITライセンスのOSSとして公開されています。

Mermaidで書いたダイアグラムを見てみましょう。

Mermaidテキスト
flowchart LR
A(空腹) -->|食事| B(腹八分)
B -->  C{まだ食べる?}
C -->|Yes| D[血糖値スパイク]
C -->|No| E[おいしかった^^]

どうでしょうか?
位置を調整することなく、簡単に整理されたダイアグラムが作成できました。
一番の長所は、ここから変更点がある場合に微調整する必要がない点です。

以下は2行だけ加えて分岐を増やしたものです。

Mermaidテキスト
flowchart LR
A(空腹) -->|食事| B(腹八分)
A(空腹) -->|食事| B'(満腹)
B -->  C{まだ食べる?}
C -->|Yes| D[血糖値スパイク]
C -->|No| E[おいしかった^^]
B' --> D[血糖値スパイク]

なお、Mermaid記法を適用する場合はコードブロックを「```mermaid」と書く必要があります。

QiitaはMermaidに対応しています。
上の図も直接Mermaid記法で書いています。

データベースからER図を作成する

MermaidはER図も簡単に作図することができます。

ER図も作成してみましょう。ただし、普通に作成すると面白くないので既存のデータベースから逆輸入してみます。

※ IntelliJ IDEA や DBeaver で簡単にER図を作成できるのはナイショ

ということで、PostgreSQLとMermaidを使って、作成済みのデータベースからER図を作成してみます。

データの用意

PostgreSQL 標準のベンチマークツールである pgbench を使ってデータベースを用意します。

事前に「pgbenchdb」という名前の適当なデータベースを作成しておき、pgbench を実行します。
pgbench コマンドのオプションについては以下を参照ください。

性能測定は行わず、データベースの作成のみを実行します。

$ pgbench -i -I dtGvpf pgbenchdb

pgbench で作成されるテーブルは以下の4つです。

pgbenchで作成されたテーブル
pgbenchdb=# \d+ pgbench_accounts
                                   テーブル"public.pgbench_accounts"
    列    |    タイプ     | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 圧縮 | 統計目標 | 説
 
----------+---------------+----------+---------------+------------+------------+------+----------+----
--
 aid      | integer       |          | not null      |            | plain      |      |          | 
 bid      | integer       |          |               |            | plain      |      |          | 
 abalance | integer       |          |               |            | plain      |      |          | 
 filler   | character(84) |          |               |            | extended   |      |          | 
インデックス:
    "pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
外部キー制約:
    "pgbench_accounts_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench_branches(bid)
参照元:
    TABLE "pgbench_history" CONSTRAINT "pgbench_history_aid_fkey" FOREIGN KEY (aid) REFERENCES pgbench
_accounts(aid)
アクセスメソッド: heap
オプション: fillfactor=100

    
pgbenchdb=# \d+ pgbench_branches
                                   テーブル"public.pgbench_branches"
    列    |    タイプ     | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 圧縮 | 統計目標 | 説
 
----------+---------------+----------+---------------+------------+------------+------+----------+----
--
 bid      | integer       |          | not null      |            | plain      |      |          | 
 bbalance | integer       |          |               |            | plain      |      |          | 
 filler   | character(88) |          |               |            | extended   |      |          | 
インデックス:
    "pgbench_branches_pkey" PRIMARY KEY, btree (bid)
参照元:
    TABLE "pgbench_accounts" CONSTRAINT "pgbench_accounts_bid_fkey" FOREIGN KEY (bid) REFERENCES pgben
ch_branches(bid)
    TABLE "pgbench_history" CONSTRAINT "pgbench_history_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench
_branches(bid)
    TABLE "pgbench_tellers" CONSTRAINT "pgbench_tellers_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench
_branches(bid)
アクセスメソッド: heap
オプション: fillfactor=100

pgbenchdb=# \d+ pgbench_history 
                                          テーブル"public.pgbench_history"
   列   |           タイプ            | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 圧縮 | 統
計目標 | 説明 
--------+-----------------------------+----------+---------------+------------+------------+------+---
-------+------
 tid    | integer                     |          |               |            | plain      |      |   
       | 
 bid    | integer                     |          |               |            | plain      |      |   
       | 
 aid    | integer                     |          |               |            | plain      |      |   
       | 
 delta  | integer                     |          |               |            | plain      |      |   
       | 
 mtime  | timestamp without time zone |          |               |            | plain      |      |   
       | 
 filler | character(22)               |          |               |            | extended   |      |   
       | 
外部キー制約:
    "pgbench_history_aid_fkey" FOREIGN KEY (aid) REFERENCES pgbench_accounts(aid)
    "pgbench_history_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench_branches(bid)
    "pgbench_history_tid_fkey" FOREIGN KEY (tid) REFERENCES pgbench_tellers(tid)
アクセスメソッド: heap

      
pgbenchdb=# \d+ pgbench_tellers
                                    テーブル"public.pgbench_tellers"
    列    |    タイプ     | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 圧縮 | 統計目標 | 説
 
----------+---------------+----------+---------------+------------+------------+------+----------+----
--
 tid      | integer       |          | not null      |            | plain      |      |          | 
 bid      | integer       |          |               |            | plain      |      |          | 
 tbalance | integer       |          |               |            | plain      |      |          | 
 filler   | character(84) |          |               |            | extended   |      |          | 
インデックス:
    "pgbench_tellers_pkey" PRIMARY KEY, btree (tid)
外部キー制約:
    "pgbench_tellers_bid_fkey" FOREIGN KEY (bid) REFERENCES pgbench_branches(bid)
参照元:
    TABLE "pgbench_history" CONSTRAINT "pgbench_history_tid_fkey" FOREIGN KEY (tid) REFERENCES pgbench
_tellers(tid)
アクセスメソッド: heap
オプション: fillfactor=100

データベースをSQLファイルに変換する

ER図へ変換する前に、先ほど作成したデータベースをSQLファイルに変換します。
変換のためにpg_dumpを利用します。

pg_dumpはデータベースをバックアップすることのできるコマンドです。他のユーザによるデータベースへのアクセス(読み書き)をブロックしないため、データベースが運用中でもダンプしてスクリプトファイルやアーカイブファイルとして抽出することができます。

データ定義情報のみ取り出したいので、-s (--schema-only) オプションを付ける必要があります。

$ pg_dump -s pgbenchdb > pgbenchdb-schema-only.sql

今回、データベース単位でスクリプトを作成しましたが、各テーブルごとにスクリプトを作成することもできます。

ここまでで、PostgreSQLでの操作は以上です。

SQLからMermaid記法へ変換する

次に、SQLファイルをMermaid記法に変換させる必要があります。

自力で書いてもいいですが、LLMを使って変換させちゃいましょう。

以下のように1文だけ添えて、SQLの中身をコピペしました。
「以下のSQLをmermaid記法に変換してください。~~~」

出力過程は以下を参照ください。

履歴には表示されていませんが、
SQLの中身をバッククォート3つ「```」で囲むとSQLの内容がうまく反映されます。

私の感覚ですが、Mermaid記法への変換精度は高いです。
今回のようなSQLからの変換に限らず、「Mermaid記法」という単語を使用することである程度完成度の高いソースコードが作成されます。

今回、変換前(SQLファイル)と変換後(Mermaidテキスト)を比較してどの程度の精度で変換できたのかは重要ではないので、ほとんど修正せずにそのまま使用します。

作成したMermaidテキストを画像、pdfへ出力する

Mermaidで図示する方法はいくつもあります。
とりあえず試してみたい方は Mermaid Live Editor がオススメです。

今回、VSCodeの拡張機能のみを利用して画像、pdfへ出力します。
使用する拡張機能は以下です。

先ほど作成したMermaidテキストを「.md」拡張子で作成します。

その後、コマンドパレット(ctrl + shift + p)でMarkdown:Open Preview to the Sideを選択して
プレビューを確認できます。

vscode_preview.png

結果がいい感じなら。Markdown側で右クリックを押下し、好きな形式に変換します。

menu.png

ただし、このままだと図を書き出せず、Markdownのままになってしまいます。

解決策は以下の記事を参考にさせていただきました。

VSCodeの設定からMarkdown-pdf: Mermaid Serverで以下のように設定してください。
(2024/12/03 時点でも、10.5.0以降のバージョンを指定するとうまく変換してくれませんでした。)

setting.png

これで図を書き出せるようになりました。

最終的に作成したER図はこちら。

Mermaidテキスト
erDiagram
    PG_BENCH_ACCOUNTS {
        INTEGER aid PK 
        INTEGER bid FK
        INTEGER abalance
        CHAR(84) filler
    }
    PG_BENCH_BRANCHES {
        INTEGER bid PK 
        INTEGER bbalance
        CHAR(88) filler
    }
    PG_BENCH_HISTORY {
        INTEGER tid FK 
        INTEGER bid FK 
        INTEGER aid FK 
        INTEGER delta
        TIMESTAMP mtime
        CHAR(22) filler
    }
    PG_BENCH_TELLERS {
        INTEGER tid PK 
        INTEGER bid FK 
        INTEGER tbalance
        CHAR(84) filler
    }

    %% Relationships
    PG_BENCH_ACCOUNTS ||--|| PG_BENCH_BRANCHES : "bid"
    PG_BENCH_HISTORY ||--|| PG_BENCH_ACCOUNTS : "aid"
    PG_BENCH_HISTORY ||--|| PG_BENCH_BRANCHES : "bid"
    PG_BENCH_HISTORY ||--|| PG_BENCH_TELLERS : "tid"
    PG_BENCH_TELLERS ||--|| PG_BENCH_BRANCHES : "bid"

おわりに

PostgreSQLとMermaid を使って、データベースからER図を出力する方法を紹介しました。

結論、皆さんに伝えたいのが Mermaidはいいぞ ということです。

ただし、CSSでデザインを変更できるのですが、ピクセル単位での位置調整はできないことがたまにキズ。
利用ケースとしては、仕事の成果物として利用するのは難しくても、確認段階での利用に適しているのかなと思います。

記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。

14
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?