Flyway × Spring Boot:整合與使用指南(含版本管理觀念與實務流程)
Flyway 是一套 資料庫版本控管(Schema Migration) 工具。
你可以把它想成「DB 的 Git log + 部署腳本管理」:
- 每次 DB 結構變更(DDL)與必要資料(部分 DML)都用一個 migration 檔記錄
- Flyway 在啟動或部署時自動執行「尚未執行過」的 migration
- DB 內會有一張歷史表追蹤版本與 checksum,避免環境漂移
1. Flyway 解決什麼問題?
1.1 確保環境一致
同一套 migrations 在 dev/sit/uat/prod 跑出相同的 DB 結構(schema)。
1.2 變更可追蹤、可審核
每個版本變更都是一個檔案,可 code review、可回溯原因。
1.3 部署更可靠
部署時只要跑 Flyway,就能把 DB 從「目前版本」補到「最新版本」。
Flyway 的設計偏向 forward-only:用新版本修正問題,而不是自由切換版本。
2. Flyway 版本管理核心概念
2.1 Migration 檔 = DB 版本
V1__init.sqlV2__add_user_table.sqlV3__add_index_on_user.sql
命名規則(最常用的版本化 migration):
V<版本號>__<描述>.sql2.2 Flyway 會在 DB 建一張歷史表
預設表名:flyway_schema_history
表裡會記錄:
- version / description
- installed_on
- checksum(避免你偷偷改已執行過的檔)
- success/failure
2.3 啟動時會不會每次都從 V1 跑?
- 第一次(全新 DB):會從 V1 跑到最新
- 之後每次啟動:只跑「新加的版本」
3. 在 Spring Boot 中整合 Flyway
3.1 加入依賴
Maven
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>Gradle
implementation 'org.flywaydb:flyway-core'你的 JDBC driver(PostgreSQL/SQL Server/Oracle)通常本來就會有。
3.2 放置 migrations
預設路徑:
src/main/resources/db/migration範例:
src/main/resources/db/migration/V1__init.sql
CREATE TABLE app_user (
id BIGINT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL
);src/main/resources/db/migration/V2__add_last_login_at.sql
ALTER TABLE app_user ADD last_login_at TIMESTAMP NULL;3.3 application.yml 基本設定
spring:
flyway:
enabled: true
locations: classpath:db/migration只要你有設定 spring.datasource.*,Spring Boot 會在啟動時自動跑 Flyway。
4. 常見進階設定(實務很常用)
4.1 舊資料庫接管(baseline)
如果你的 DB 已經有很多表,但以前不是 Flyway 管的,直接 migrate 可能被擋(schema 非空)。
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1含義:
- 建立
flyway_schema_history - 把「現在」當作 baseline 起點
- 後續從更高版本開始管理
4.2 指定只跑到某個版本(target)
你可以控制「最多 migrate 到哪個版本」,例如只跑到 V10:
spring:
flyway:
target: 10使用情境:
- 分階段上線(SIT/UAT 先追新,Prod 暫時停在某版)
4.3 Repeatable migrations(R__)
適合用在 View / Stored Procedure / Function 等會反覆更新的物件。
命名:
R__<描述>.sql例:R__create_or_replace_views.sql
特性:
- 內容有變(checksum 變)→ 下次 migrate 會再跑
4.4 多 schema / 自訂歷史表
spring:
flyway:
schemas: app_schema
table: flyway_schema_history5. 正常團隊流程:誰要動 DB 該怎麼做?
5.1 DDL(建表/加欄位/索引/約束)
一律新增 migration 檔(不要手改正式 DB,也不要回頭改舊 migration)。
正確:新增 V12__add_xxx.sql
錯誤:改 V1__init.sql 或改已上線跑過的版本(checksum 會炸)。
5.2 DML(資料)要不要用 migration 管?
分兩類:
A) 測試資料 / 個人資料
- dev 手動增刪改 OK
- 但不保證別人環境也有
B) 系統必要資料(seed data)
例如:SYS_SETTING、權限角色、字典資料、必要參數
- 建議用 migration 管
- 否則會發生「我本機正常、SIT/UAT 缺資料爆掉」
範例:V5__seed_sys_setting.sql
INSERT INTO sys_setting (k, v) VALUES ('TOKEN_EXPIRE_MIN', '15');6. 開發環境手動改 DB 會怎樣?(重要)
6.1 手動改 DDL 的風險
- 環境漂移:你本機 DB 跟別人不同
- 之後 migration 會撞到「欄位已存在」導致啟動失敗
建議:DDL 不要手改,直接寫 migration。
6.2 手動改資料的影響
- 測試資料:OK
- 必要 seed:最好寫進 migration
6.3 本機亂掉的最乾淨解法
- 砍掉 dev DB(或清空 schema)重建
- 讓 Flyway 從 V1 跑到最新
正式環境通常不允許 clean;dev 可以用「重建 DB」解決。
7. Flyway vs Hibernate ddl-auto
ddl-auto=create/update:方便但不可控、難審核、容易飄移- Flyway:可控、可審核、可重播,較適合正式環境
常見配置:
- 正式:Flyway 管 schema
- JPA:
ddl-auto=validate或none
8. 實務建議(讓團隊跑得穩)
所有 DDL 都走 migration(禁止手改正式 DB)
migration 一旦進環境就不要改內容(避免 checksum 問題)
需要回滾:
- 正式環境以備份還原最可靠
- 或新增修復 migration 往前修
View/SP 用
R__*.sql管理必要的系統參數/字典資料用 seed migrations 管理
9. 快速檢查清單
9.1 基本必備
- 依賴已加入:
org.flywaydb:flyway-core - JDBC Driver 已加入:PostgreSQL / SQL Server / Oracle 對應 driver(專案能正常連線 DB)
- Datasource 設定正確:
spring.datasource.url / username / password(與環境一致) - migrations 路徑正確:預設
classpath:db/migration(或spring.flyway.locations已正確指定) - 檔名規則正確:
V<版本>__<描述>.sql(注意雙底線__,版本號建議用遞增整數或語意化序列) - 第一次啟動:DB 會建立
flyway_schema_history(代表 Flyway 有在跑) - 之後啟動:只會執行「新增且尚未執行」的版本(不會每次從 V1 重跑)
9.2 團隊流程必備(避免環境漂移)
- 已跑過的 migration 檔不要修改(避免 checksum 不一致導致啟動失敗)
- 所有 DDL 變更都用新增 migration(不要手動改正式 DB;dev 也盡量不要手改 DDL)
- PR/Code Review 檢查:migration 是否可重播、是否破壞相容(例如欄位改型別、drop 欄位)
- 部署順序固定:先跑 Flyway(migrate)→ 再部署應用程式(避免程式先上但 DB 還沒更新)
9.3 常見設定檢查(視情況)
- 既有 DB 接管:若 schema 非空且之前不是 Flyway 管的,考慮:
spring.flyway.baseline-on-migrate=true - 分階段上線:需要控制只跑到某版時,設定:
spring.flyway.target=<version> - Repeatable:View / SP / Function 等需要可重複更新者,用
R__*.sql - 多 schema:需要時設定
spring.flyway.schemas=...(並確認權限足夠) - 禁止危險操作:正式環境避免開
clean(若你有用到 Flyway 的 clean 機制)
9.4 與 JPA/Hibernate 搭配(建議)
- 正式環境:
spring.jpa.hibernate.ddl-auto建議validate或none(避免 Hibernate 直接改 schema) - 開發環境:仍建議 Flyway 管 schema;
ddl-auto只用validate輔助檢查(避免 update 自動改表造成不可控差異) - 啟動順序:確保 Flyway 在 JPA 初始化前完成 migrate(Spring Boot 預設通常會幫你處理)
如果你願意貼你的 application.yml(datasource + flyway + jpa),我可以幫你對照這份清單逐項檢查哪裡少了/可能踩雷。