今からでも遅くない
DBマイグレーション
- Flyway と SchemaSpy の紹介 -
2021-11-12 社内勉強会
onozaty
DBマイグレーション
• 本スライドでのDBマイグレーションとは、データベースのスキーマ
やデータを変更する作業
• アプリケーションのコードと同じように、データベースも変化して
いくので、データベースの構造もバージョン管理していく必要があ
る
• 様々な環境(本番環境、開発者個人のローカル環境、CI環境など)に対して、
同じように変更が適用できるように
• 現在どのような状態になっているのかが明確になるように
DBマイグレーションで利用されるライブラリ
• フレームワーク自体でDBマイグレーションの仕組みが提供されてい
るものも多い
• Ruby on Rails、Laravel、Django など
• フレームワークに依存せず単独で使えるライブラリ/ツールもあり
• Flyway、LiquiBase、golang-migrate など
DBマイグレーションの仕組み
• マイグレーションのためのSQLやコードをバージョン毎に管理
• それらを順次実行していくことでマイグレーションを実現
• 積み重ねた後のものが、現在の状態を表すものになる
CREATE TABLE products
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
description text,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL
);
class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
DBマイグレーションに何を使うか
• フレームワークに用意されているものがあればそれを使う
• フレームワーク自体に無くても、フレームワークと組み合わせて便
利に使えそうなものがあればそれを
• なければCLIとして使える好きなものを
Flyway
Flyway
• Javaで実装されたマイグレーションツール
• SQLまたはJavaでマイグレーションを記述する
• Javaでのマイグレーションは、SQLで書くのが難しいようなときに
• JavaのメジャーなフレームワークのSpring Bootでは、依存関係とし
てFlywayを追加するだけで、アプリケーション起動時にマイグレー
ションを行ってくれるようになる
• クラスパスからマイグレーションを拾ってくれる
• 単独のCLIツールとしても使える
Flywayの使い方 (CLI)
1. Flywayをダウンロード
2. DB接続先を設定
3. マイグレーションで実行するSQLファイルを作成
4. マイグレーション実行
1. Flywayをダウンロード
下記から利用プラットフォームに応じたものをダウンロードする。
• https://flywaydb.org/download/community
$ wget https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/8.0.2/flyway-commandline-8.0.2-linux-
x64.tar.gz
$ tar zxvf flyway-commandline-8.0.2-linux-x64.tar.gz
$ ls -l flyway-8.0.2/
total 40
drwxrwxr-x 2 vagrant vagrant 4096 Oct 30 00:10 conf
drwxrwxr-x 3 vagrant vagrant 4096 Oct 30 00:10 drivers
-rwxr--r-- 1 vagrant vagrant 4044 Oct 20 15:38 flyway
-rw-r--r-- 1 vagrant vagrant 3869 Oct 20 15:40 flyway.cmd
drwxrwxr-x 2 vagrant vagrant 4096 Oct 30 00:10 jars
drwxr-xr-x 7 vagrant vagrant 4096 Oct 20 15:40 jre
drwxrwxr-x 6 vagrant vagrant 4096 Oct 30 00:10 lib
drwxrwxr-x 2 vagrant vagrant 4096 Oct 30 00:10 licenses
-rw-r--r-- 1 vagrant vagrant 699 Oct 20 15:38 README.txt
drwxrwxr-x 2 vagrant vagrant 4096 Oct 30 00:10 sql
実行に必要なもの(Javaのランタイムや主要なJDBCドライバ)も同梱されているので、追加で何かインストールしたり
ダウンロードする必要なし
2. DB接続先を設定
conf/flyway.conf にDB接続先を設定。
~/flyway-8.0.2$ vi conf/flyway.conf
flyway.url=jdbc:postgresql://192.168.33.10:5432/testdb
flyway.user=user1
flyway.password=password1
conf/flyway.conf
3. マイグレーションで実行するSQLファイルを作成
sql/ 配下にSQLファイルを作成。
~/flyway-8.0.2$ vi sql/V1__create_initial_tables.sql
CREATE TABLE customers (
customer_id serial PRIMARY KEY,
name text NOT NULL,
mail_address text NOT NULL
);
sql/V1__create_initial_tables.sql
V1__create_initial_tables.sql
Prefix
Version
Separator Suffix
Description
4. マイグレーション実行
flyway migrate でマイグレーション実行。
~/flyway-8.0.2$ ./flyway migrate
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Successfully validated 1 migration (execution time 00:00.025s)
Creating Schema History table "public"."flyway_schema_history" ...
Current version of schema "public": << Empty Schema >>
Migrating schema "public" to version "1 - create initial tables"
Successfully applied 1 migration to schema "public", now at version v1 (execution time 00:00.061s)
4. マイグレーション実行
テーブルが作成されていることを確認。
~/flyway-8.0.2$ psql -U user1 testdb
psql (13.4)
Type "help" for help.
testdb=> ¥d customers
Table "public.customers"
Column | Type | Collation | Nullable | Default
--------------+---------+-----------+----------+------------------------------------------------
customer_id | integer | | not null | nextval('customers_customer_id_seq'::regclass)
name | text | | not null |
mail_address | text | | not null |
Indexes:
"customers_pkey" PRIMARY KEY, btree (customer_id)
testdb=>
マイグレーションを追加
新しいバージョンのファイルを追加することで、マイグレーションが
追加される。
試しにバージョン2としてカラム(phone_number)を追加するSQLファ
イルを追加してみる。
~/flyway-8.0.2$ vi sql/V2__add_phone_number.sql
ALTER TABLE customers ADD COLUMN phone_number VARCHAR(20);
sql/V2__add_phone_number.sql
マイグレーションを追加
flyway migrate で再度マイグレーション実行。
~/flyway-8.0.2$ ./flyway migrate
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Successfully validated 2 migrations (execution time 00:00.054s)
Current version of schema "public": 1
Migrating schema "public" to version "2 - add phone number“
Successfully applied 1 migration to schema "public", now at version v2 (execution time 00:00.083s)
マイグレーションを追加
カラム(phone_number)が追加されていることを確認。
~/flyway-8.0.2$ psql -U user1 testdb
psql (13.4)
Type "help" for help.
testdb=> ¥d customers
Table "public.customers"
Column | Type | Collation | Nullable | Default
--------------+-----------------------+-----------+----------+------------------------------------------------
customer_id | integer | | not null | nextval('customers_customer_id_seq'::regclass)
name | text | | not null |
mail_address | text | | not null |
phone_number | character varying(20) | | |
Indexes:
"customers_pkey" PRIMARY KEY, btree (customer_id)
testdb=>
マイグレーション実行状況の確認
マイグレーションの実行状況は flyway info で確認できる。
※ flyway_schema_historyというテーブルがFlywayにより作成され、そこで情報が管理されている
~/flyway-8.0.2$ ./flyway info
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Schema version: 2
+-----------+---------+-----------------------+------+---------------------+---------+----------+
| Category | Version | Description | Type | Installed On | State | Undoable |
+-----------+---------+-----------------------+------+---------------------+---------+----------+
| Versioned | 1 | create initial tables | SQL | 2021-10-30 01:26:12 | Success | No |
| Versioned | 2 | add phone number | SQL | 2021-10-30 05:20:02 | Success | No |
+-----------+---------+-----------------------+------+---------------------+---------+----------+
DBマイグレーションを途中から導入
• Flywayはスキーマ内に既にテーブルがある状態でマイグレーション
を開始するとエラーになる
• 空の状態から始めることを前提としており、既にテーブルがある=状態が
おかしいとみなされる
• 既に運用されているDBに対して途中からマイグレーションを導入す
る方法として、baseline という機能が用意されている
• 現在のDBのバージョンをFlywayに教えて、そのバージョン以前のマイグ
レーションは、既に適用済みとして管理する
バージョン1を適用済みとした場合
baselineとしてバージョン1を指定する。
現在のバージョンが1となり、バージョン2以降が適用対象となる。
~/flyway-8.0.2$ ./flyway baseline -baselineVersion=1
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Creating Schema History table "public"."flyway_schema_history" with baseline ...
Successfully baselined schema with version: 1
~/flyway-8.0.2$ ./flyway info
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Schema version: 1
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
| Category | Version | Description | Type | Installed On | State | Undoable |
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
| | 1 | << Flyway Baseline >> | BASELINE | 2021-10-30 08:01:12 | Baseline | No |
| Versioned | 2 | add phone number | SQL | | Pending | No |
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
バージョン1を適用済みとした場合
この状態でflyway migrateを行うと、バージョン2から適用される。
~/flyway-8.0.2$ ./flyway migrate
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Successfully validated 2 migrations (execution time 00:00.054s)
Current version of schema "public": 1
Migrating schema "public" to version "2 - add phone number"
Successfully applied 1 migration to schema "public", now at version v2 (execution time 00:00.075s)
~/flyway-8.0.2$ ./flyway info
Flyway Teams Edition 8.0.2 by Redgate
Database: jdbc:postgresql://192.168.33.10:5432/testdb (PostgreSQL 13.4)
Schema version: 2
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
| Category | Version | Description | Type | Installed On | State | Undoable |
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
| | 1 | << Flyway Baseline >> | BASELINE | 2021-10-30 08:01:12 | Baseline | No |
| Versioned | 2 | add phone number | SQL | 2021-10-30 08:17:45 | Success | No |
+-----------+---------+-----------------------+----------+---------------------+----------+----------+
DBマイグレーションを途中から導入
• プロジェクトに途中から導入する場合、現在のDBの状態をバージョ
ン1として一つのSQLファイルにし、baselineとしてバージョン1を
設定すればすぐに始められる
• 初期化用のDDLあれば、それをそのままバージョン1のSQLとして入れる
• 万が一DDLが無くてDBしかない場合には、dumpなどでDLL吐き出していれ
るなど
ちょっと話変わって
DBマイグレーションとER図
DBマイグレーションとER図
• ER図やテーブル定義書みたいなものを、DBマイグレーションと別
に管理するのは難しい
• DBマイグレーションによって出来上がるものと、ER図やテーブル定義書が
アンマッチになりかねない
• DBマイグレーション後のDBから、ER図やテーブル定義書を作るこ
とでアンマッチを防ぐ
SchemaSpy
SchemaSpy
• DBの情報を元に、ER図やテーブル、カラム一覧などの情報をHTML
形式のドキュメントとして出力するツール
• DBの構造を確認するのにとても便利
どんなものが出来上がるのかは、下記
サンプルが参考になる
• https://schemaspy.org/sample/index.html
SchemaSpyの使い方
• 事前準備
• 設定
• 実行
細かい説明は下記の記事にまとめているので参考に
• https://zenn.dev/onozaty/articles/schema-spy-er
SchemaSpy – 事前準備
各種ファイルのダウンロード+インストールを実施。
• https://schemaspy.readthedocs.io/en/latest/installation.html
• SchemaSpyのjarファイル入手
• Java8以降のインストール
• 対象のDBに応じたJDBCドライバの入手
• Graphvizのインストール(オプション)
事前準備はそこまで面倒じゃないが、Docker Imageが提供されていて、
そちらを使うことで事前準備が省略できるのでおススメ。
• https://hub.docker.com/r/schemaspy/schemaspy/
SchemaSpy – 設定
設定ファイルを作成。
# type of database. Run with -dbhelp for details
schemaspy.t=pgsql11
# optional path to alternative jdbc drivers.
schemaspy.dp=drivers
# database properties: host, port number, name user, password
schemaspy.host=192.168.33.10
schemaspy.port=5432
schemaspy.db=testdb
schemaspy.u=user1
schemaspy.p=password1
# output dir to save generated files
schemaspy.o=output
# db scheme for which generate diagrams
schemaspy.s=public
schemaspy.properties
SchemaSpy – 実行
実行。
Docker Image利用時は下記のように実行。
~$ ls -1R
.:
drivers
schemaspy-6.1.0.jar
schemaspy.properties
./drivers:
postgresql-42.2.23.jar
~$ java -jar schemaspy-6.1.0.jar
~$ sudo docker run -v "$PWD/output:/output" -v "$PWD/schemaspy.properties:/schemaspy.properties" ¥
schemaspy/schemaspy:latest
参考サイト
• Flyway公式サイトのドキュメント
(ここ読めば全部書いてある)
• https://flywaydb.org/documentation/
• SchemaSpy公式サイトのドキュメント
(ここ読めばほとんど書いてある)
• https://schemaspy.readthedocs.io/en/latest/
• SchemaSpyのDocker Imageの利用方法
• https://hub.docker.com/r/schemaspy/schemaspy/

今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -