今天會有這篇因為我換了一台電腦開發,問題馬上就出現了。
我的資料庫服務跑在本地,當我換了一台電腦,所有資料庫的設定都要重新來一次
就算我可以拿docker-compose.yml再啟一個相同的PostgreSQL資料庫,裡面也沒有相同的資料表,需要重新執行SQL 腳本才行,麻煩呀。而且儘管把觀點拓展,不限於我的專案,開發時也可能遇到這些問題:
你可能會說,記得執行 SQL 腳本就好,但這容易出錯且難以管理。
這個時候Flyway 可以解決這些問題。
Flyway 是一個開源的資料庫遷移工具,主要特點:
1. 加入依賴
在 pom.xml 中加入 Flyway 依賴:
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
Spring Boot 會自動偵測並啟用 Flyway。
2. 配置設定
在 application.yml 中配置 Flyway:
flyway:
enabled: true
baseline-on-migrate: true
locations: classpath:db/migration
validate-on-migrate: true
out-of-order: false
table: flyway_schema_history
baseline-version: 1
3. 建立遷移檔案
在 src/main/resources/db/migration/ 目錄下建立 SQL 檔案,命名規則:V{版本號}__{描述}.sql
以我的專案為例,建立初始資料庫結構:
**檔案:**V1__Initial_schema.sql
-- 啟用 UUID 生成功能
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- 建立枚舉類型
CREATE TYPE record_source AS ENUM ('LIVE', 'MANUAL');
-- 使用者表
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255),
name VARCHAR(255),
google_sub VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 活動表
CREATE TABLE activities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
target_time INT NOT NULL DEFAULT 0,
color VARCHAR(16),
icon VARCHAR(16),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 活動記錄表
CREATE TABLE activity_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
activity_id UUID NOT NULL REFERENCES activities(id) ON DELETE CASCADE,
source record_source NOT NULL,
duration INT CHECK (duration IS NULL OR duration > 0),
executed_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 建立索引
CREATE UNIQUE INDEX idx_users_google_sub ON users (google_sub);
CREATE INDEX idx_activities_user ON activities(user_id);
CREATE INDEX idx_records_user_time ON activity_records(user_id, executed_at DESC);
當 Spring Boot 應用程式啟動時,Flyway 會自動執行以下步驟:
flyway_schema_history
表都設定好就可以啟動系統,看看遷移有沒有成功
此時所有表都成功建立了(但資料沒有,這正常)
還有一張flyway_schema_history 來記錄flyway的執行狀況,下次啟動時會根據這張表的紀錄來決定是否執行遷移檔(V1__Initial_schema.sql)的內容。
同時 Flyway 也會建立一張 “flyway_schema_history” 來記錄執行狀況。
下次啟動時,會依據這張表的紀錄來判斷是否需要再次執行 V1__Initial_schema.sql