カラーミーショップ ECブログリレー

tblsを導入してDBドキュメントを継続的にメンテナンスする

カラーミーショップ ECブログリレー

EC事業部でシニアエンジニアリングリードをしているkenchanです。この記事はEC事業部ブログリレーの4日目の記事で、3日目はakatsuuraによるRuby のコードリーディング会に参加して1年経ちましたでした。

カラーミーショップの開発チームでは、2020年末にデータベースドキュメンテーションツールとしてtblsを導入しました。本記事では、tblsの機能や導入の狙いから、実際の移行のプロセスをふりかえり、最後に今後やっていきたいことについて紹介します。データベースドキュメントの継続的なメンテナンスに課題を感じている方の参考になれば幸いです。

tblsとは何か

k1LoW/tblsは、ホスティング事業部の@k1LoWが開発、メンテナンスをしているデータベースのドキュメンテーションツールです。tblsを使うことで、MySQLやPostgreSQLなどのRDBMSはもちろん、BigQueryやRedshiftなど様々なDBMSのスキーマ情報からドキュメントを生成することができます。また、実行ファイルはワンバイナリのため環境への依存が少なく、CIなどへの組み込みが容易という特徴も持っています。実際に生成されるドキュメントはリポジトリにあるsampleにある通り、Markdown形式のテーブル定義とSVG形式のER図です。

前述の特徴をうまく活用することで、以下のような効果が得られると考えています。

  1. DBスキーマと乖離しない生きたドキュメントにできる
  2. 制約がドキュメントに反映されるため堅いDB設計のインセンティブが高まる
  3. 複数のDBMSでドキュメントのフォーマットを統一できる

1つ目は言わずもがな、ドキュメントの生成元はデータベースのスキーマ情報になるので、ドキュメントの更新忘れを仕組みで防ぐのが容易になります。2つ目については、外部キー制約を設定することでER図がリッチになりますし、enum型など制約の強い型を使うことがドキュメントを充実させることに繋がります。堅いDB設計をすることがデータの堅牢性を高めるだけでなく、ドキュメントのメンテナンスコストを削減することにもなるということです。最後の効果は、現代の大規模アプリケーションが複数のDBMSを使い分けていることに起因します。読者のみなさんも、アプリケーションのデータを保存するのはRDBMSで、分析基盤としてRedshiftやBigQueryを利用するというケースが多いのではないでしょうか。そういった状況においては、ドキュメントのフォーマットや書き方が統一できるというのは大きなメリットになりえます。

以上の効果を期待し、カラーミーショップではデータベースドキュメントツールとしてtblsを導入することを決めました。

tbls以前のカラーミーショップのDBドキュメント

カラーミーショップでは、tbls導入前もデータベースドキュメントがもちろんありましたが、DDLに自然言語でコメントをつける形式で、フォーマットが決まっているわけではありませんでした。実際のドキュメントの一部をお見せすると、以下のようなテーブル単位のドキュメントが用途ごとにいくつかのMarkdownファイルに分かれて存在している状態でした。

## mfa_requests: 多要素認証の利用開始申請

```sql
CREATE TABLE `mfa_requests` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `account_id` VARCHAR(10) NOT NULL,
  `method` VARCHAR(255) NOT NULL, -- "sms": SMS認証
  `token` VARCHAR(6) NOT NULL, -- 多要素認証利用開始時の認証に使うトークン
  ...
  `created_at` DATETIME NOT NULL,
  `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `account_id` (`account_id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
...

ドキュメントの作成や更新は、スキーマ更新をする開発者とレビュアーに頼っており、カラムの増減や取りうる値の更新などが漏れてしまう場合がありました。開発者であればコードや変更履歴を追うことでドキュメントと実態の差異に気づくこともできますが、分析などのためにデータを閲覧しているディレクターやカスタマーサポートにとってはドキュメントだけが頼りであり、これが継続的にメンテナンス出来ていないことは事業部全体の課題でした。

tblsへの移行プロセス

前述の通り、移行前にも価値のあるドキュメントは存在していたため、これをうまくtblsへと移行する作業を行うことにしました。これは以下のような手順で進めました。

  1. 既存のドキュメントを.tbls.yml形式に変換する
  2. tblsでドキュメントを生成して差異が出たところを修正する
  3. tblsによるドキュメント更新方法を周知する

1. 既存のドキュメントを.tbls.yml形式に変換する

tblsは、DBのスキーマから取得した情報だけでなくYAMLファイルを使ってドキュメントに情報を追加できます。README.mdにあるCommentsRelationsのような情報を記述することで、メタデータや制約がなくてもドキュメントの情報量を増やせます。まずは、既存のドキュメントをこの方法で移行することにしました。

前章で紹介したMarkdown形式のドキュメントは、明確なフォーマットはありませんでしたが緩やかな共通点はありました。

  • テーブル名はh2相当の見出しで、コロンに続いて日本語の説明がある
  • カラムの説明はDDLのカラムの後ろにSQLのコメントか何らかの区切り文字を挟んで入っている
    • ない場合もあるし、複数行の場合もある
    • SQLとしてSyntax Errorになっているものもある
  • DDL以外の箇所にテーブルについてのドキュメントがある

MarkdownとSQLのパーサーを組み合わせることである程度情報を抽出できそうでしたが、DDLの部分がSyntax Errorになっているのが無視できない量あったため、ファイルを行単位で読み込んでパースするスクリプトを自作しました。そのスクリプトによって約400テーブルのドキュメントをYAML化した後、いくつかのエッジケースを手作業で移行しました。

2. tblsでドキュメントを生成して差異が出たところを修正する

最初の作業では、DBスキーマとドキュメントの乖離は考慮していませんでした。そのため、生成した.tbls.ymlと最新のスキーマからドキュメントの生成を行って差異がないかを確認しました。tblsは、YAMLのコメントと実際のデータベースに差異があるときはエラーとして報告してくれます。これを繰り返し、古くなっているドキュメントを1つ1つ直していきました。幸運にも、テーブルやカラムの有無に関する古い情報は両手で足りる程度でした。

なお、最終的な.tbls.ymlが4000行を超えてしまっているため、k1LoW/tbls-buildを使ったファイルの分割を検討しています。

3. tblsによるドキュメント更新方法を周知する

最後に、tblsをつかったドキュメントの作成・更新をするためのコマンドとドキュメントを作成しました。カラーミーショップの開発環境はすべてDockerコンテナを使うようになっているため1、まずはリポジトリにある.tbls.ymlとDockerコンテナとして動いているDBからドキュメントを作成・更新できるようにしました。実際に運用を始めてみたところ、一時的に検証のために追加したカラムやインデックスの差分が出るケースもあったため、ドキュメント生成用のDBを都度用意してスキーママイグレーションを最初から実行するという運用をしています。Makefileは以下のようなイメージです。Ruby on Railsを利用している方はなんとなくイメージできるかと思います。

.PHONY: doc/schema
doc/schema:
	@docker-compose run --rm -e ENV=tbls db bundle exec rake db:drop
	@docker-compose run --rm -e ENV=tbls db bundle exec rake db:setup
	@docker-compose run --rm -e ENV=tbls db bundle exec rake db:migrate
	@docker-compose run --rm tbls doc -f

まとめと今後の展望

この記事では、2020年末に実施したtbls導入の狙いと実際のプロセスを紹介しました。カラーミーショップでは、開発者以外もRedashを利用してデータの検索・分析を行うため、誰もが安心して使える生きたドキュメントを、妥当なコストでメンテナンスし続ける仕組みが必要とされていました。tblsは社内の実績も豊富で、前述の課題を解決するための最適なツールだと考えています。

一方で、改善できる点はまだまだあります。

  • 開発プロセスへ組み込む(CI/CD)
  • カラムに対するドキュメントの網羅率の向上させる
  • ログ基盤として利用しているBigQueryに導入する

これらの施策を進め、カラーミーショップの開発ドキュメントの拡充と、開発組織全体のデータ分析能力の向上を目指していきたいと思います。