🦍

データベースを絶対にドキュメンテーションする

2023/10/08に公開

DBのドキュメントを書くのはつらい

DBのドキュメント書くのめんどくさい…書かなくていいなら書きたくない…それが私の本音です。
でもどうしてDBのドキュメントを書くのが辛いんでしょうか?

開発が進む方が目に見えて成果が出ている感じがするから

開発は多くの場合時間との戦いです。会社のキャッシュに限りがあったり、お客さんへの納期が厳しかったり、コスト意識が高かったり、色々ですが、開発にはスピードが求められることが多いです。そんな中、コードを書く手を止めてドキュメントを書くのは恐怖すら感じることもあるのではないでしょうか。

メンテナンスされないから

日々の開発・運用の中でDBの関連する箇所が追加・変更・削除された場合、ドキュメントも合わせて変更されなければいけません。しかし、往々にしてドキュメントの更新は忘れ去られます。理由は様々ですが、よくあることです。

後回しにしているから

必要になったタイミングでドキュメントを書くというのは、DB設計時に書くよりも遥に辛いことが多いです。なぜなら憶えていないし、ドキュメントを書くために他の作業を止めないといけない…
結局最初から書いた方が楽だし早いという諦めで私はドキュメントを最初から残すことに決めました。

コードのコメントよりも距離が遠いから

DBのドキュメントはコードコメントよりも視覚的に距離が遠いです。コードコメントは定義と同じか近くのブロック/行に対して、ありますが、DBの場合はテーブル・カラムコメントをしてもテーブル定義を見にいくSQLを叩かなければ見ることはできません。

どうしてDBのドキュメントが必要か

めんどくさいDBのドキュメント…でも書かなければいけないのはなぜか、それは

  • 再来月の全て忘れた自分のため
  • 開発チームに新規参加したメンバーのため
  • 運用チームがSQLでDBにアクセスしてトラブルシュートするため
  • 解析チーム、データ基盤チームが既存のDBの内容を理解するため

です。下に行くほど、「コードに書いてあるので読んでください」とは言いづらいです。そもそもDBの中身がコードを見てわかる保証もありません。

どのようなドキュメントを残すか

DBのドキュメントには色々なものがあると思いますが、私は以下の物を作成します。

ドキュメントの種類 何のために使うか 何を残すか
テーブル一覧、ER図 DBの全体像を把握する テーブル名、テーブル同士の関連、テーブルの概要
テーブル詳細 格納されるデータの概要を理解する 個別のテーブルのカラムの型、カラムの説明
集約の定義、説明 テーブル同士の関係、ユースケースとテーブルの関係を理解する 集約ごとのテーブル一覧、スキーマ上に表現されない制約、関連するユースケース

集約について

DBのドキュメントの際に集約という言葉はあまり使われないので補足で説明します。
ここでの集約とは、「トランザクションごとの整合性を保つ単位」です。
DDDにおける集約を意識しており、それをDBの文脈で読み替えたものです。

DDDにおける集約(Aggregates)とは、オブジェクトのまとまりを表し、整合性を保ちながらデータを更新する単位

具体的にドキュメントに記載されるのは、「何の概念を表現している集約か」、「どういう制約があるか」、「どのようなユースケースの時にデータが作成、参照されるか」です。集約をドキュメント内に定義することで、テーブル単体では得られない複数テーブル間の情報を表現することができます。それにより、より高次元でのテーブルのユースケースと制約について理解する手助けとなります。集約とユースケースは密接に紐づいており、集約の説明に代表的なユースケースを記載することで両者の理解が深まります。

ドキュメントのつらみを少しでもなくす

とてもつらいDBのドキュメンテーションですが、少しでも楽に意味のあるドキュメントを作成&メンテナンスしていく方法があります。
それはこちらです。

  1. よく見るところ(ソースコード)の近くに置いておいて存在を意識できるようにする
  2. 実際のDBスキーマから自動生成する
  3. CI/CDでドキュメントがあることをチェックして先送りを防止する

tblsを使ってMarkdownでDBのドキュメントを生成する

上で説明したドキュメントについて、tblsというツールを使うと、多くの部分を自動で生成してくれます。Markdown形式で生成してくれるため、ソースコードと同じ場所を見れば参照することができ、ドキュメントのlint機能も兼ね備えているため、CI/CDでドキュメント作成をある程度強制して、後回しにされてメンテされなくなってしまうのを防げます。

tblsを使うと上記のテーブル一覧、ER図、テーブル詳細については何もしなくても生成されます。テーブルコメント、カラムコメントからテーブルの説明、カラムの説明を設定してくれます。

ref:https://github.com/k1LoW/tbls/tree/v1.70.0?tab=readme-ov-file#document-a-database

tblsについては作者の@k1LoWさんがPHP Confで発表した資料が参考になるのでこちらをご参照ください。

具体的な実装方法はメルカリさんやマネーフォーワードさんがかなりわかりやすくまとめてくださっているのでそちらをご参照いただくのがわかりやすいと思います。
https://engineering.mercari.com/blog/entry/20220425-2b2162c214/
https://moneyforward-dev.jp/entry/2023/09/27/135320

とはいえ、tbls自体かなりシンプルな構造なので本家READMEを読むだけで十分なことが多いです。

Viewpointsを集約として利用する

Viewpointsはtblsのユニークな機能で、DBスキーマ上に存在しないテーブル間の関係をビューポイントとして表現することができます。
viewpoints

今回はこの機能を使って集約を表現することにしました。

ドキュメントがメンテナンスされない問題に立ち向かう

tblsがスキーマからドキュメントが自動生成されるとはいえ、テーブル名とカラム名だけがあってもドキュメントとは呼ぶことはできません。
適切なテーブルコメント、カラムコメントを設定することでドキュメントとして機能します。
tblsにはlint機能があり、テーブルコメント、カラムコメントを設定してあるかチェックすることができ、こちらをCIに組み込むことでこれらのコメントの設定を強制することができます。

https://github.com/k1LoW/tbls/blob/main/README.md#lint-a-database

また、Viewpointsについても最新版(v1.70.0)のtblsではrequireViewpointsを設定することで、全てのテーブルはいづれかのViewpointsに含まれていなければCIが落ちるようにすることが可能になりました。
これで、Viewpointsの付け忘れもなくなり、集約も含めて必ずメンテナンスされている状態を維持できるようになりました。

GitHubで編集を提案
株式会社MICIN

Discussion