隨着項目的不斷迭代,數據庫表結構、數據都在發生着變化。甚至有的業務在多環境版本並行運行。數據爲王的時代,管理好數據庫的版本也成爲了迫切的須要。如何能作到像 Git 之類的版本控制工具來管理數據庫?Java 項目中經常使用 Flyway 和 Liquibase 來管理數據庫版本。其中 Flyway 相對來講比較受歡迎。html
Flyway 大受歡迎是由於它具備如下優勢:mysql
Flyway 須要在 DB
中先建立一個 metadata
表 (缺省表名爲 flyway_schema_history
), 在該表中保存着每次 migration
(遷移)的記錄, 記錄包含 migration
腳本的版本號和 SQL 腳本的 checksum
值。下圖表示了多個數據庫版本。web
對應的 metadata
表記錄:spring
installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | Initial Setup | SQL | V1__Initial_Setup.sql | 1996767037 | axel | 2016-02-04 22:23:00.0 | 546 | true |
2 | 2 | First Changes | SQL | V2__First_Changes.sql | 1279644856 | axel | 2016-02-06 09:18:00.0 | 127 | true |
Flyway 掃描文件系統或應用程序的類路徑讀取 DDL 和 DML 以進行遷移。根據metadata
表進行檢查遷移。若是腳本聲明的版本號小於或等於標記爲當前版本的版本號之一,將忽略它們。其他遷移是待處理遷移:可用,但未應用。最後按版本號對它們進行排序並按順序執行 並將執行結果寫入 metadata 表。sql
對應的 metadata
表記錄:數據庫
installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | Initial Setup | SQL | V1__Initial_Setup.sql | 1996767037 | axel | 2016-02-04 22:23:00.0 | 546 | true |
2 | 2 | First Changes | SQL | V2__First_Changes.sql | 1279644856 | axel | 2016-02-06 09:18:00.0 | 127 | true |
3 | 2.1 | Refactoring | JDBC | V2_1__Refactoring | axel | 2016-02-10 | 17:45:05.4 | 251 | true |
Flyway 支持命令行(須要下載命令行工具)和 Java Api ,也支持構建工具 Maven 和 Gradle 。這裏咱們將目光放在 Java Api 上。app
Flyway 是如何比較兩個 SQL 文件的前後順序呢?它採用 採用左對齊原則, 缺位用 0 代替 。舉幾個例子:spring-boot
1.0.1.1 比 1.0.1 版本高。工具
1.0.10 比 1.0.9.4 版本高。oop
1.0.10 和 1.0.010 版本號同樣高, 每一個版本號部分的前導 0 會被忽略。
Flyway 將 SQL 文件分爲 Versioned 、Repeatable 和 Undo 三種:
checksum
有變更, Flyway 就會從新應用該腳本. 它並不用於版本更新, 這類的 migration
老是在 Versioned 執行以後才被執行。這三種的命名規則以下圖:
V
表示 Versioned, R
表示 Repeatable, U
表示 Undo.
或下劃線 _
__
_
或空格
分隔.sql
Spring Boot 提供了對 Flyway 的自動配置 。使咱們能夠開箱即用 Flyway 進行數據庫版本控制。
你只須要引入依賴:
<!-- 無需版本號 -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
複製代碼
固然你要集成你的相關數據庫環境。這裏咱們採用 H2 數據庫來演示,其它數據庫同理只不過方言不一樣。不熟悉 H2 數據庫的可參閱個人專題文章 Spring Boot 2 實戰:H2數據庫集成以及使用 。
爲了直觀的講解配置,首先在 Spring Boot 配置文件 application.yml
咱們配置 H2 數據庫爲:
spring:
datasource:
# h2 驅動
driver-class-name: org.h2.Driver
# h2 數據庫 持久化到磁盤D:/h2 庫名: flyway mysql模式
url: jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE
h2:
# 開啓console 訪問 默認false
console:
enabled: true
settings:
# 開啓h2 console 跟蹤 方便調試 默認 false
trace: true
# 容許console 遠程訪問 默認false
web-allow-others: true
# h2 訪問路徑上下文
path: /h2-console
複製代碼
對應Flyway的配置爲:
# flyway 配置
spring:
flyway:
# 啓用或禁用 flyway
enabled: true
# flyway 的 clean 命令會刪除指定 schema 下的全部 table, 生產務必禁掉。這個默認值是 false 理論上做爲默認配置是不科學的。
clean-disabled: true
# SQL 腳本的目錄,多個路徑使用逗號分隔 默認值 classpath:db/migration
locations: classpath:db/migration
# metadata 版本控制信息表 默認 flyway_schema_history
table: flyway_schema_history
# 若是沒有 flyway_schema_history 這個 metadata 表, 在執行 flyway migrate 命令以前, 必須先執行 flyway baseline 命令
# 設置爲 true 後 flyway 將在須要 baseline 的時候, 自動執行一次 baseline。
baseline-on-migrate: true
# 指定 baseline 的版本號,默認值爲 1, 低於該版本號的 SQL 文件, migrate 時會被忽略
baseline-version: 1
# 字符編碼 默認 UTF-8
encoding: UTF-8
# 是否容許不按順序遷移 開發建議 true 生產建議 false
out-of-order: false
# 須要 flyway 管控的 schema list,這裏咱們配置爲flyway 缺省的話, 使用spring.datasource.url 配置的那個 schema,
# 能夠指定多個schema, 但僅會在第一個schema下創建 metadata 表, 也僅在第一個schema應用migration sql 腳本.
# 但flyway Clean 命令會依次在這些schema下都執行一遍. 因此 確保生產 spring.flyway.clean-disabled 爲 true
schemas: flyway
# 執行遷移時是否自動調用驗證 當你的 版本不符合邏輯 好比 你先執行了 DML 而沒有 對應的DDL 會拋出異常
validate-on-migrate: true
複製代碼
請務必仔細閱讀 Flyway 相關配置的說明。
咱們先編寫一個初始化 SQL 文件,向 H2 數據庫已經自動初始化的 schema flyway
添加一張 sys_user
表。請注意命名規則。腳本名稱爲 V1.0.1__Add_table_user.sql
。SQL 腳本的位置在配置的 spring.flyway.locations
下。內容爲:
use `flyway`;
CREATE TABLE `sys_user`
(
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(1024) NOT NULL unique ,
`encode_password` varchar(1024) NOT NULL,
`age` int(3) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
insert into flyway.sys_user values (1,'Felordcn','{noop}12345',18);
複製代碼
啓動 Spring Boot 應用 。打開 H2 數據庫控制檯 http://localhost:8080/h2-console
,在 JDBC URL 一欄粘貼 jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE
並點擊 Connect
按鈕會進入如下界面:
這裏 -1
是由於咱們缺省了 Flyway 須要的 flyway_schema_history
表 。0
是由於 H2 數據庫自動初始化了 Schema flyway
,其它數據庫可能須要你手動來創建。
咱們編寫一個 V1.0.0__Delete_sysuser_felordcn.sql
來刪除 V1.0.1__Add_table_user.sql
中初始化的用戶。你會發現啓動報錯了,由於咱們開啓了校驗,因此對於邏輯錯誤的版本會拋出異常。咱們將版本號更改成 V1.0.2__Delete_sysuser_felordcn.sql
再次啓動。經過 H2 數據庫控制檯咱們會發現多了一條變動記錄:
同時 sys_user
表的數據也沒有了,符合預期。
經過上面的介紹相信你很快就會使用 Flyway 進行數據庫版本控制了。這裏總結了一些在實際開發中的使用經驗:
spring.flyway.cleanDisabled=false
。V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql
,這種命名同時也能夠獲取更多腳本的開發者和相關功能的信息。spring.flyway.outOfOrder
取值 生產上使用 true
,開發中使用 false
。schema
時配置spring.flyway.table
爲不一樣的系統設置不一樣的 metadata
表名而不使用缺省值 flyway_schema_history
。今天咱們對 Flyway 數據庫版本遷移管理工具進行了介紹並將之與 Spring Boot 相結合。這將大大規範咱們的數據庫管理,提升生產效率。同時也分享了一些至關有用的生產實踐經驗。
** 相關的 DEMO 可經過關注公衆號:Felordcn
回覆 flyway
進行獲取。**
關注公衆號:Felordcn獲取更多資訊