PlantUMLでER図を書いて、githubで管理してみた

# きっかけ
趣味のWebサイト制作で頭の整理のためにシーケンス図等を書きたいなーと思ったので、
PlantUMLを使って書いた後にどうせならドキュメントでPlantUMLにできるところを
PlantUMLにしてしまおうと思い立ったのがきっかけです。

# PlantUMLとは
PlantUMLはシーケンス図やクラス図等のダイアグラムを
text形式で記述できる方式です。

## メリット
- text形式だからgit等で差分を取りやすい
- vscode等のIDEの自動補完機能を使用すればかなりの速度でUML図を書けるようになる

後述のchrome拡張機能もあり、全てをtextで管理したいがちなエンジニアにとっては
良いツールとなっているのではと思います。
スニペットもうまく使っていければ高速で記述できそうです。

## デメリット
- 学習コストが高い(ように感じた)
- 実際に生成される図を見ながらでないと整った図が書けないのでプレビューを表示しながら編集できるエディターがほぼ必須

慣れないうちは作図ツールなどで作ってしまった方が早い
グループで運用するなら環境をある程度合わせなければならないという点に
大きなデメリットがあると感じました。

# 環境
エディターはVisual Studio Code
拡張機能「Markdown Preview Enhanced」をインストールする。

Markdownファイル(.md)内で下記のように
コードブロックの言語に「puml」を指定すると上記拡張機能のプレビューで
ダイアグラムに変換されるようになります。
※ @startuml,@endumlを付けるのは、
vscode拡張機能PlantUMLでの表示、画像エクスポートと、
後述のchrome拡張を用いたgithub上での図変換のためです。

\`\`\`puml
@startuml

(ここにPlantUML記法で記述)

@enduml
\`\`\`


# エンティティの記述
Class図のフォーマットを使って各エンティティを記述していきます。
Class図では下記のように定義することでエンティティを表すことができます。

```puml
@startuml
entity "employee" {

}
@enduml
```


#### 表示
![employee.png](https://qiita-image-store.s3.amazonaws.com/0/204347/cad76059-1ced-885f-ccf1-76fea0d971cf.png)

----


PlantUMLでER図を書くに当たり、
以下のような規則を決めて運用することにしました。

## SQLDataType

- `{カラム名}:DataType`として記述する

#### 例
varchar(128)の`name`カラムを定義する場合

```puml
@startuml
entity "employee" {
    name:varchar(128)
}
@enduml
```

#### 表示
![datatype.png](https://qiita-image-store.s3.amazonaws.com/0/204347/77c6f34b-a71f-74fd-0441-f065cf070b2d.png)

## Primary Key
- カラム名の前に`+`を付ける。(図では緑色の〇になる)
- カラム名の後に`[PK]`を付ける
- カラムの下に二重線(`==`)を引き、他のカラムと分割する

#### 例
`id`をPrimary Keyとする場合

```puml
@startuml 
entity "employee" {
    + id [PK]
    ==
    name:varchar(128)
}
@enduml
```
#### 表示
![primarykey.png](https://qiita-image-store.s3.amazonaws.com/0/204347/367b1fc7-9c4e-fb70-0982-c52eda9d2e65.png)


## Foreign Key

- カラム名の前に`#`を付ける(図では黄色の□になる)
- カラム名の後に[FK(tablename,columnname)]を付ける

#### 例
`company_id`がcompanyテーブルの`id`を参照する場合

```puml
@startuml
entity "employee" {    
    + id [PK]   
    ==
    # company_id [FK(company,id)]    
    name:varchar(128)
}
@enduml
```

####表示
![foreignkey.png](https://qiita-image-store.s3.amazonaws.com/0/204347/12553bf6-eb3a-4975-7215-ab28539c3de6.png)

## Unique
- カラム名の前に`*`を付ける(図では●になる)

####例
```
@startuml
entity "employee" {
    + id [PK]
    ==
    # company_id [FK(company,id)]
    * employee_code:varchar(16)
    name:varchar(128)
}
@enduml
```

####表示
![unique.png](https://qiita-image-store.s3.amazonaws.com/0/204347/3890acee-157e-f27a-69a1-6c1f9a0cf1ab.png)

## Relation
### one to one

```puml
@startuml
Entity1||--||Entity2
@enduml
```
####表示
![onetoone.png](https://qiita-image-store.s3.amazonaws.com/0/204347/1b5e1a2a-05c0-fa42-fadc-306fcc590b42.png)

### one to many
#### 1. zero or many

```puml
@startuml
Entity1 --o{ Entity2
@enduml
```
####表示
![zeroormany.png](https://qiita-image-store.s3.amazonaws.com/0/204347/cfd5b16d-cf26-7e93-211e-238da8aee663.png)

#### 2. one or many

```puml
@startuml
Entity1 --|{ Entity2
@enduml
```
####表示
![oneormany.png](https://qiita-image-store.s3.amazonaws.com/0/204347/60a35b04-b49b-324b-c293-0523e54a487f.png)

### many to many
```puml
@startuml
Entity1 }--{ Entity2
@enduml
```
####表示

![manytomany.png](https://qiita-image-store.s3.amazonaws.com/0/204347/aaa401a4-3b34-cd2a-8277-b5cf9cc99000.png)


# 記述例

```puml
@startuml samplediagram
title Sample ERDiagram
entity "entity1" {
    + id [PK]
    ==
    # entity2_id [FK(entity2,id)]
    # entity4_id [FK(entity4,id)]
    * code:varchar(64)
    name:varchar(128)
}

entity "entity2" {
}

entity "entity3" {
}

entity "entity4" {
}


entity1} o-- entity2

entity1 --{ entity3
entity1 }--{ entity4
@enduml
```
####表示
![samplediagram.png](https://qiita-image-store.s3.amazonaws.com/0/204347/269eb2eb-a6df-a38e-604a-ada5d0654979.png)

# その他
他にもエンティティの配置やエンティティを示すEの文字、背景色の変更等、細かい調整もできるみたいです。

そのあたりは参考にさせて頂いた下記サイトが詳しく解説してくれていました。
[PlantUMLでER図を描く！](https://medium.com/veltra-engineering/how-to-draw-er-diagram-with-plantuml-86ec2095645e)


ただ、あまりにこだわりすぎるとメンテナンス性が落ちそうなので
ほどほどにするのがよさそうな気がします。

#githubでの管理
## githubでPlantUMLをダイアグラムとして表示する
chromeの拡張機能、[Pegmatite](https://chrome.google.com/webstore/search/Pegmatite)をインストールすることで、
github上のMarkdownファイルのコードブロックに
PlantUMLでの記述があったら自動でダイアグラムに変換して表示してくれるようになります。

これによって、シーケンス図なども図に変換して表示してくれるようになるので、
githubでの設計レビューが捗りそうです。
当然、元はtextファイルなので差分の比較わかりやすいですし、
修正もパワポ、Excelをこねくり回すよりかは楽になります。

あとはキーボードショートカットで変換機能のオンオフを切り替えられればとても嬉しい。


# 所感
- Primary KeyとForeign Keyの記述は冗長すぎるような気がする。
特にForeign Keyで、テーブル名とカラム名が長かったりすると図のバランスに影響してしまう。

- わかりやすさを求めるならRelationを表す線の上にどこのカラムを結び付けているかを書いた方がよさそう。

- テキストで記述でき、拡張機能のおかげでgithub上での図表示もできるのは大きなメリット。Markdownの延長として流行ってほしい。ただ、色々できるだけに、学習コストが高く、ER図描画ツールを使った方がSQL文の生成も含めて圧倒的に楽ということでなかなか難しそう。

- ER図が一定の記法で書かれるようになれば(公式が示してくれればいいのですが)、
PlantUMLのER図からCreateSQL文や
各言語のフレームワークのMigrationファイルを生成できそうですが・・・
まだまだ下記のような個人レベルでの動きなので先は長い。
   > 1. [plantuml2mysql](https://github.com/grafov/plantuml2mysql)
   > 2. [planter](https://github.com/achiku/planter)


# 最後に
完全に自分ルールなので、ここはこうしたらいいんじゃないかとか、
自分はこうしてるとかがあればぜひご意見を頂きたいです。

まだまだ運用を始めた段階なのでよりブラッシュアップしていこうと思います。