10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ZYYXAdvent Calendar 2019

Day 2

A5:SQL Mk-2 に頼らない MySQL のテーブル定義出力

Last updated at Posted at 2019-12-01

こちらは ZYYX Advent Calendar 2019 2日目の記事です。

テーブル定義書の生成といえば、おなじみの A5:SQL Mk-2 でエクセルベースのテーブル定義書をエクスポートするのが定番ですが、残念ながら Windows のみで Mac に対応していません。
Wine で強引に exe を実行するという方法もありますが、今回はよりカジュアルに Mac でHTML・Markdownでテーブル定義書を書き出す方法をご紹介します。

  • mysqldump で DDL をXML形式で出力
  • XSLT をあててHTMLやMarkdown に変換

以上の流れになります。

DDLのエクスポート

まずは mysqldump コマンドでXML形式のDDLをエクスポートします。

mysqldump -u <ユーザー名> -p --no-data --xml <データベース名> > <出力ファイル名(XML)>

XSLT のアタッチ

dump した XML に xsltproc で変換したいフォーマット用のXSLTをあてて変換します。

# HTMLに変換
xsltproc -o <出力ファイル名(HTML)> htmlstyle.xslt <XMLファイルパス>

# Markdownに変換
xsltproc -o <出力ファイル名(md)> mdstyle.xslt <XMLファイルパス>

htmlstyle.xsl(HTMLに変換)

<?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="html" encoding="utf8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>

	<xsl:template match="database">
		<html lang="ja">
			<head>
				<meta charset="utf-8"/>
				<title><xsl:value-of select="@name"/> テーブル定義</title>
				<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
				<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"/>
				<style>
					table.htable {
						margin: 3em auto 1em auto !important;
					}
					table.htable th {
						border-left: 10px solid #e5e5e5 !important;
					}
					footer {
						border-top: 1px solid #e5e5e5;
						padding: 0.5em;
					}
				</style>
			</head>

			<body>
				<div class="container">
					<h1 class="page-header"><xsl:value-of select="@name"/> テーブル定義</h1>
					<xsl:apply-templates select="table_structure"/>
				</div>
				<footer class="text-center">
					your company
				</footer>
			</body>
		</html>
	</xsl:template>

	<xsl:template match="table_structure">
		<h2 class="table-header"><xsl:value-of select="@name"/></h2>
		<table class="table table-bordered htable">
			<tbody>
				<tr class="active">
					<th>論理テーブル名</th>
					<td>
						<xsl:value-of select="options/@Comment"/>
					</td>
				</tr>
				<tr class="active">
					<th>物理テーブル名</th>
					<td><xsl:value-of select="@name"/></td>
				</tr>
			</tbody>
		</table>
		<table class="table table-condensed">
			<thead>
				<tr>
					<th class="text-right">#</th>
					<th>論理名</th>
					<th>物理名</th>
					<th>データ型</th>
					<th>NULL</th>
					<th>デフォルト値</th>
					<th>主キー</th>
					<th>ユニーク</th>
				</tr>
			</thead>
			<tbody>
				<xsl:apply-templates select="field"/>
			</tbody>
		</table>
		<table class="table table-condensed">
			<thead>
				<tr>
					<th>インデックス名</th>
					<th>カラム</th>
					<th>複合キー順序</th>
					<th>NULL</th>
					<th>UNIQ</th>
				</tr>
			</thead>
			<tbody>
				<xsl:apply-templates select="key"/>
			</tbody>
		</table>
	</xsl:template>

	<xsl:template match="field">
		<tr>
			<td class="text-right"><xsl:value-of select="position()"/></td>
			<td><xsl:value-of select="@Comment"/></td>
			<td><xsl:value-of select="@Field"/></td>
			<td><xsl:value-of select="@Type"/></td>
			<td><xsl:if test="@Null='YES'"><span class="glyphicon glyphicon-ok"></span></xsl:if></td>
			<td><xsl:value-of select="@Default"/></td>
			<td><xsl:if test="@Key='PRI'"><span class="glyphicon glyphicon-ok"></span></xsl:if></td>
			<td><xsl:if test="@Key='UNI'"><span class="glyphicon glyphicon-ok"></span></xsl:if></td>
		</tr>
	</xsl:template>

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

mdstyle.xsl(Markdownに変換)

<?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:value-of select="@name"/> テーブル定義
<xsl:apply-templates select="table_structure"/>
</xsl:template>

<xsl:template match="table_structure">

## <xsl:value-of select="@name"/>
物理テーブル名|論理テーブル名
--------|--------
<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="position()"/>| <xsl:value-of select="@Comment"/> |<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="@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>

変換文書のイメージ

HTML
image.png

Markdown
image.png

HTML では bootstrap を読み込んでいるので、Webフォントなどのアイコンも利用できます。
MySQL テーブル仕様書メーカー的な何か の XSLT をベースにさせていただきました。

まとめ

XML と XSLT を使用して様々なフォーマットに変換することができました。
標準では対応していない形式でもちょっとした応用をするだけで変換できそうですね。

外部キー制約とかトリガーが XML にダンプされていませんが、これは --xml モードの場合、mysqlsump 内部で show keys from <テーブル名> コマンドを使った出力をしているためです。
バグとして公式のバグトラッカーに起票されていますが、結構昔なので対応されることはなさそうですね(笑)https://bugs.mysql.com/bug.php?id=66821

テーブル定義書としては「片手落ち」なので、あくまでカジュアルに定義を確認したい時などに使用範囲はとどめておきましょう。

10
7
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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?