MySQL のスキーマ定義を Markdown にして Wiki に貼る

# 背景

- テーブル定義を自動生成したい
- ファイルで管理したくない
- プロジェクト管理ツールの Wiki に貼りたい

# TL;DR

- mysqldump でスキーマのみ XML 形式で出力して
- xsltproc で XML を Markdown 形式に変換して
- Wiki に貼る

# 環境

- MySql Server version: 5.7.23-0ubuntu0.16.04.1 (Ubuntu)
- Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-130-generic x86_64)

# スキーマ定義のエクスポート

mysqldump でスキーマ定義のみ、XML形式で出力

```
$ sudo mysqldump --no-data --xml [対象データベース] -u[ユーザー] -p > [エクスポートファイル]
例：
$ sudo mysqldump --no-data --xml sakila -uroot -p > sakilaDump.xml
```

# xsltproc で XML を Markdown に変換

## xsltproc のインストール

```
$ sudo apt-get install xsltproc
```

## Markdown 形式に変換

- 変換用のスタイル定義ファイル

```xml:mdstyle.xsl
<?xml version="1.0" encoding="utf8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://sqlfairy.sourceforge.net/sqlfairy.xml">
<xsl:output method="text" encoding="utf8"/>

<xsl:template match="database">
# テーブル定義
<xsl:apply-templates select="table_structure"/>
</xsl:template>

<xsl:template match="table_structure">

## <xsl:value-of select="@name"/>
TBL物理名|TBL論理名（コメント）
--------|--------
<xsl:value-of select="@name"/>|<xsl:value-of select="options/@Comment"/>

#### カラム情報
物理名|データ型|NULL|デフォルト|キー|論理名（コメント）|Extra
----|----|----|----|----|---|---|
<xsl:apply-templates select="field"/>

#### インデックス情報
インデックス名|カラム|複合キー順序|NULL|UNIQ
----|----|----|----|----
<xsl:apply-templates select="key"/>
</xsl:template>

<xsl:template match="field">
<xsl:value-of select="@Field"/>|<xsl:value-of select="@Type"/>|<xsl:value-of select="@Null"/>|<xsl:choose><xsl:when test="@Default != ''"><xsl:value-of select="@Default"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Key != ''"><xsl:value-of select="@Key"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Comment != ''"><xsl:value-of select="@Comment"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Extra != ''"><xsl:value-of select="@Extra"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="key">
<xsl:value-of select="@Key_name"/>|<xsl:value-of select="@Column_name"/>|<xsl:value-of select="@Seq_in_index"/>|<xsl:choose><xsl:when test="@Null != ''"><xsl:value-of select="@Null"/></xsl:when><xsl:otherwise>NO</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Non_unique = '0'">YES</xsl:when><xsl:otherwise>NO</xsl:otherwise></xsl:choose>|<xsl:text>
</xsl:text>
</xsl:template>

</xsl:stylesheet>
```

- 変換

```
$ xsltproc -o [アウトプットファイル] [スタイル定義ファイル] [対象XMLファイル]
例：
$ xsltproc -o sakila-db.md mdstyle.xsl sakilaDump.xml
```

# Wiki に貼る（サンプル）

以下のような感じ

## テーブル定義

## actor
TBL物理名|TBL論理名（コメント）
--------|--------
actor|

#### カラム情報
物理名|データ型|NULL|デフォルト|キー|論理名（コメント）|Extra
----|----|----|----|----|---|---|
actor_id|smallint(5) unsigned|NO|n/a|PRI|n/a|auto_increment|
first_name|varchar(45)|NO|n/a|n/a|n/a|n/a|
last_name|varchar(45)|NO|n/a|MUL|n/a|n/a|
last_update|timestamp|NO|CURRENT_TIMESTAMP|n/a|n/a|on update CURRENT_TIMESTAMP|


#### インデックス情報
インデックス名|カラム|複合キー順序|NULL|UNIQ|
----|----|----|----|----|
PRIMARY|actor_id|1|NO|YES|
idx_actor_last_name|last_name|1|NO|NO|

## actor_info
TBL物理名|TBL論理名（コメント）
--------|--------
actor_info|VIEW

#### カラム情報
物理名|データ型|NULL|デフォルト|キー|論理名（コメント）|Extra
----|----|----|----|----|---|---|
actor_id|smallint(5) unsigned|NO|0|n/a|n/a|n/a|
first_name|varchar(45)|NO|n/a|n/a|n/a|n/a|
last_name|varchar(45)|NO|n/a|n/a|n/a|n/a|
film_info|text|YES|n/a|n/a|n/a|n/a|

# 参考

- [mysqldumpまとめ](https://qiita.com/PlanetMeron/items/3a41e14607a65bc9b60c)
- [MySQLのテーブル定義書を自動更新する環境を作った](https://qiita.com/RyutaKojima/items/c287cf5d4c1ff5d35502)
- [Linux - XML に XSLT を適用して HTML 生成！](https://www.mk-mode.com/octopress/2015/09/07/linux-apply-xslt-to-xml-by-xsltproc/)