DB定義書・テーブル定義書作成からの脱却
目次
みなさんテーブル定義を書いてますか?
ほとんどの方はテーブル定義を書かれていると思います。
ただプロジェクトが完成したり、再度改修された時、そのテーブル定義書は最新ですか?
途中から参加したプロジェクト、リプレースのために調べた旧システムのテーブル定義が実際とは異なっていることがよくありませんか?
もちろん初期段階では必要です
もちろん初期段階でテーブル構成を検討するためには暫定として作成することは大事です。
特にウォーターフォール型の開発などでは必須でしょう。
SchemaSpyという選択肢
それではER図、テーブル定義を最新な状態に保つにはどうするべきでしょうか?
チーム内で必ず定義を更新することを徹底することでしょうか?
いいえ、ここでSchemaSpyです!Dockerのコンテナの一つとしてSchemaSpyを導入しておくと、DB接続情報さえ指定しておけば実行時に最新のテーブル定義を作成し、外部キーを適切に設定しておくとER図も自動的に生成してくれます。
この環境を作っておけばSchemaSpyを実行するたびに最新のDB定義を閲覧可能になります。
個人的にですがアジャイル開発の場合は脳内に想定したテーブル構成のマイグレーションファイルを一気に作成し、SchemaSpyでDB定義を作成してお客様にテーブル構成などを見ていただく場合もあります。
以下自動生成された定義の例です。
かなり見やすくて本格的なER図、テーブル定義が出力されていますね。
管理者ユーザIDに設定した外部キーのリレーションもちゃんと反映されています。

ER図の一部の例

テーブル定義の例
マイグレーションファイル作成時の注意点
極力各カラムのコメントはつけるようにしましょう。各カラムが何の役割なのかテーブル定義上で分かりやすくなります。
またテーブル自体にもコメントとしてテーブル名を指定するようにしましょう。
テーブル一覧のコメント欄にテーブル名として反映することが出来ます。
Schema::create("admin_users", function (Blueprint $table) {
$table->id();
$table->string('email',255)->comment('email');
$table->string('password',255)->comment('ハッシュ化したパスワード');
$table->string('name',255)->comment('名前');
$table->string('token', 255)->nullable()->comment('トークン');
$table->datetime('token_expired_at')->nullable()->comment('トークン有効期限');
$table->timestamps();
$table->softDeletes();
$table->comment('管理者ユーザ')
$table->unique('email', 'ui_admin_users_email');
$table->unique('token', 'ui_admin_users_token');
});
Docker上での設定例
docker-compose.yml
schemaspy:
build: ./schemaspy
volumes:
- ./schemaspy/result:/app/html:rw
- ./schemaspy/config/schemaspy.properties:/app/schemaspy.properties:ro
environment:
DB_CONNECTION: ${DB_CONNECTION}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
working_dir: "/app"
command: "java -jar schemaspy.jar"
schemaspy/Dockerfile
FROM openjdk:8u121-jdk-alpine
ENV TZ=Asia/Tokyo \
DB_CONNECTION=mysql \
DB_HOST=db \
DB_PORT=3306 \
DB_DATABASE=laravel_local \
DB_USERNAME=phper \
DB_PASSWORD=secret \
LOG_CHANNEL=stder \
DRIVER_URL=http://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar \
APP_URL=https://github.com/schemaspy/schemaspy/releases/download/v6.0.0-rc2/schemaspy-6.0.0-rc2.jar
WORKDIR /app
RUN apk --update add graphviz ttf-dejavu && \
apk --update add --virtual .builddep tzdata wget libressl && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
wget -O mysql-connector-java.jar ${DRIVER_URL} && \
wget -O schemaspy.jar ${APP_URL} && \
apk del .builddep && \
rm -rf /var/cache/apk/*
※例はver.6のrc2ですが、適宜新しいバージョンのShemaSpyと合致したバージョンのjavaを指定してください。
※上記はMySQLの例ですので異なるDBの場合は適切なドライバを指定してください。
Dockerコンテナ作成時の注意点
単純にSchemaSpyコンテナを作成するとdocker-compose up -d 実行時に毎回SchemaSpyが実行されて開発環境の起動に時間がかかってしまいます。
以下のようにコマンド実行の設定(最下行のcommand:の部分)を変更しておくと常に待機状態になります。
docker-compose.yml
schemaspy:
build: ./schemaspy
volumes:
- ./schemaspy/result:/app/html:rw
- ./schemaspy/config/schemaspy.properties:/app/schemaspy.properties:ro
environment:
DB_CONNECTION: ${DB_CONNECTION}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
working_dir: "/app"
command: tail -f /dev/null
※docker-compose up -d 実行時に各コンテナは非同期で立ち上がります。逆に毎回ちゃんとDB定義を作成したい場合はDB側のコンテナが立ち上がったことを監視してからSchemaSpyのコンテナを立ち上げるように設定してください。
まとめ
どうしても人間はミスや対応漏れというものが発生します。migrationファイルを作成して、DB定義を更新するといった作業も100%行われているという保証もありません。
例えば本番リリース直前で緊急改修が必要であった場合など無事リリースできたことに安堵してテーブル定義の調整などは後回しになりがちです。
またスプレッドシートなどで管理されたテーブル定義のファイルが複数存在していてどれが最新か分からなくなる場合もあります。
そういった状態を防ぐためにもこのようなツールを導入して常に最新の定義を出力出来るようにするのがおすすめです。



















