はじめに
アプリケーションを開発していると、テーブルを追加したりカラムの型を変えたりと、DB スキーマは少しずつ変わっていきます。この変更を手作業の SQL で各環境に反映していくと、「本番にこのスクリプトは当てたっけ?」という状態が発生します。
DB スキーマの変更をバージョン管理し、環境をまたいで確実に適用するためのツールがマイグレーションツールです。この記事では、その Java / Spring Boot開発で使われることが多いマイグレーションツール Flyway について、概要・類似ツールとの比較・強みと弱み・基本的な使い方を整理します。
Flyway とは
Flyway は、DB スキーマの変更を SQL スクリプトとしてバージョン管理し、順番に適用していくマイグレーションツールです。オープンソース(Apache License 2.0)で公開されていて、2019 年からは Redgate 社が開発を引き継いでいます。
一番の特徴は、設定より規約(convention over configuration)を重視した設計だと思います。V1__create_users.sql のような決まった名前の SQL ファイルを置いておけば、Flyway がファイル名からバージョンと適用順を判断して実行してくれます。XML や YAML といった独自フォーマットを覚える必要がなく、書くのは素の SQL だけです。
適用済みのマイグレーションは flyway_schema_history というテーブルに記録されます。Flyway はこのテーブルと実際のスクリプトを照合します。そこから、どこまで適用済みか、未適用はどれかを判断します。
マイグレーションの種類
Flyway のマイグレーションはファイル名の接頭辞で種類が決まります。
| 接頭辞 | 種類 | 説明 |
|---|---|---|
V |
Versioned | バージョン付き。一度だけ順番に実行される(例 V1__init.sql) |
R |
Repeatable | バージョンなし。中身が変わるたび再実行される(例 R__view.sql) |
U |
Undo | 対応する Versioned を取り消す。有償版のみ |
B |
Baseline | 既存 DB に導入するときの基準点 |
View や Stored Procedure のように「常に最新の定義で上書きしたい」ものは Repeatable、テーブル定義の変更のように「一度だけ順番に当てたい」ものは Versioned、という使い分けになります。
類似ツールとの比較
DB マイグレーションの領域では、Flyway と Liquibase の 2 つがよく比較されます。どちらも Java 製で歴史が長く、機能的にも競合しています。
| 観点 | Flyway | Liquibase |
|---|---|---|
| 変更の記述形式 | SQL が基本 | XML / YAML / JSON / SQL |
| 適用順の管理 | ファイル名のバージョン番号(線形) | changelog に定義した順序 |
| DB 非依存性 | DB 固有の SQL を書く | 抽象記法で DB 差を吸収できる |
| ロールバック | 有償版の Undo | 無償版でも対応(記述形式による) |
| 条件付き適用 | 標準では弱い | Preconditions / Contexts / Labels |
| 学習コスト | 低い(SQL だけ) | やや高い(changelog 記法) |
Flyway は「素の SQL をそのまま管理する」シンプルさ、Liquibase は「DB 非依存や条件分岐まで含めた柔軟さ」に寄っています。
強みと弱み
強み
素の SQL だけで完結するので学習コストが低く、DBA が書いた SQL をそのまま置ける点が大きいです。独自フォーマットによるロックインもありません。Spring Boot との統合が手厚く、依存を追加すればアプリ起動時に自動でマイグレーションが走ります。対応 DB も幅広く、PostgreSQL・MySQL・Oracle・SQL Server など主要なものはカバーしています。ファイル名の連番でバージョンが決まるため、適用順を追いやすいのも利点です。
弱み
線形バージョニングは分かりやすい反面、複数人が並行して同じバージョン番号のファイルを作ると衝突します(out-of-order 問題)。ロールバック(Undo)は有償版の機能なので、無償版では打ち消し用のマイグレーションを自分で書くことになります。また、一度適用したマイグレーションファイルを後から編集するとチェックサムが変わり、validate で失敗します。適用済みのファイルは修正せず、新しいバージョンを積む運用が前提です。DB 固有の SQL を書くため、複数 DB 対応は Liquibase ほど楽ではありません。
エディションは無償の Community と有償の Enterprise に分かれます。ドリフト検出や高度な Undo などは有償側の機能です。
基本的な使い方
ここでは Spring Boot と組み合わせた最小構成を示します。
開発環境
- Windows 11
- Java 25.0.3(LTS)
- Maven 3.9.16
- Spring Boot 4.1.0
- Flyway 12.10.0
- PostgreSQL 18.4
手順 1. 依存の追加
Spring Boot 4 ではモジュール分割の変更があり、flyway-core を入れただけでは自動設定が有効になりません。Flyway のスターターを追加します1。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- ... -->
</dependencies>
手順 2. マイグレーションファイルの配置
デフォルトでは src/main/resources/db/migration 配下のファイルが読み込まれます。
CREATE TABLE users (
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL DEFAULT now()
);
ファイル名は「接頭辞 V + バージョン + 区切り __(アンダースコア 2 つ)+ 説明 + .sql」の形式です。区切りがアンダースコア 1 つだと認識されないので要注意です。
手順 3. 設定と起動
application.yml に DB 接続情報を書きます。Flyway の有効化は既定でオンです。
spring:
datasource:
url: jdbc:postgresql://localhost:5432/sample
username: app
password: secret
jpa:
hibernate:
ddl-auto: validate # スキーマ管理は Flyway に任せ、JPA は検証のみ
アプリを起動すると、未適用のマイグレーションが起動時に自動で実行されます。実行後、DB には users テーブルと flyway_schema_history テーブルができます。
手順 4. 2 つ目以降のマイグレーション
カラムを追加したくなったら、既存ファイルは触らず新しいバージョンのファイルを追加します。
ALTER TABLE users ADD COLUMN name VARCHAR(100);
次回起動時、Flyway は V2 が未適用だと判断して実行します。
主なコマンド(CLI)
Spring Boot 経由ではなく、CLI や Maven プラグインから操作することもできます。よく使うのは次のあたりです。
| コマンド | 内容 |
|---|---|
migrate |
未適用のマイグレーションを適用する |
info |
各マイグレーションの適用状況を一覧表示する |
validate |
ファイルと適用済みの内容が一致するか検証する |
baseline |
既存 DB に Flyway を導入する基準点を作る |
repair |
schema_history の不整合を修復する |
まとめ
この記事では、DB マイグレーションツール Flyway の概要・比較・強み弱み・基本的な使い方を整理しました。
Flyway は素の SQL で DB スキーマをバージョン管理する、シンプルさを重視したツールです。学習コストの低さや Spring Boot との統合が強みで、一方でロールバックが有償だったり複数 DB 対応が手厚くなかったりする弱みもあります。柔軟さを求めるなら Liquibase、シンプルさを求めるなら Flyway、という整理で選ぶとよいと思います。
参考
- https://www.red-gate.com/products/flyway/
- https://documentation.red-gate.com/fd/
- https://www.liquibase.com/
- https://spring.io/blog/2025/10/28/modularizing-spring-boot/
- https://www.bytebase.com/blog/flyway-vs-liquibase/
-
Spring Boot 4 のモジュール分割により、
flyway-coreの存在だけでは自動設定されなくなりました。詳細は Spring 公式ブログ「Modularizing Spring Boot」を参照してください。 ↩