Flyway讓資料庫版本管理更簡單
來源:
Flyway是什麼
隨著專案CICD接入,一鍵啟動,敏捷開發已經成為降本提效的不二法寶,其中涉及SQL的變更還不夠智慧和自動化,因此亟需一款工具能夠幫助開發及運維人員高效簡便地完成SQL變更,Flyway正是可以滿足我們需求的一款工具。
當我們開啟Flyway的官網,在首頁可以看到關於Flyway的一段英文介紹:
Flyway是資料庫的版本控制,跨所有環境的穩健架構演變。輕鬆、愉快和簡單的SQL。
總的來說,Flyway是一款專為CI/CD打造的,能對資料庫變更做版本控制的工具。
Flyway支援的資料庫很多,主流的資料庫都能夠完美支援,官網摘抄如下:
Supported databases are Oracle, SQL Server (including Amazon RDS and Azure SQL Database), Azure Synapse
(Formerly Data Warehouse), DB2, MySQL (including Amazon RDS, Azure Database & Google Cloud SQL), Aurora MySQL,
MariaDB, Percona XtraDB Cluster, TestContainers, PostgreSQL (including Amazon RDS, Azure Database, Google Cloud
SQL, TimescaleDB, YugabyteDB & Heroku), Aurora PostgreSQL, Redshift, CockroachDB, SAP HANA, Sybase ASE,
Informix, H2, HSQLDB, Derby, Snowflake, SQLite and Firebird.
Flyway解決的問題
在專案或產品研發過程中,很難一開始就把業務理清楚,把程式碼邏輯和資料庫表設計好,因此程式碼和資料表也會在迭代週期內不斷迭代。我們都習慣使用SVN或者Git來對程式碼進行版本管理,主要是為了解決多人開發程式碼衝突和版本回退的問題。
其實,資料庫的變更也需要版本控制,在日常開發和環境部署中,我們經常會遇到下面的問題:
-
在開發環境部署程式發現報錯,定位是自己寫的SQL指令碼忘了在當前環境執行導致;
-
從Git上新down下來的程式碼執行報錯,定位發現是其他同事修改了的SQL指令碼沒有在當前環境執行導致;
-
每次釋出包都需要釋出SQL檔案包和應用程式的版本包;
-
線上環境部署報錯,發現是運維沒有按照你投產文件裡面說明的SQL指令碼執行順序操作執行導致;
-
流水線可以自動化部署程式,但是SQL指令碼還是需要手動執行或者流水線執行SQL指令碼配置比較繁瑣;
-
其他場景....
有了Flyway,這些問題都可以輕鬆的解決。Flyway可以對資料庫進行版本管理,可以自動執行SQL,能快速有效地用於迭代資料庫表結構,並保證部署到測試環境或生產環境時,資料表都是保持一致的;
Flyway主要工作流程
Flyway工作流程如下:
1、專案啟動,應用程式完成資料庫連線池的建立後,Flyway自動執行。
2、初次使用時,Flyway會建立一個flyway_schema_history表,用於記錄sql執行記錄。
3、Flyway會掃描專案指定路徑下(預設是classpath:db/migration)的所有sql指令碼,與flyway_schema_history表指令碼記錄進行比對。如果資料庫記錄執行過的指令碼記錄,與專案中的sql指令碼不一致,Flyway會報錯並停止專案執行。
4、如果校驗透過,則根據表中的sql記錄最大版本號,忽略所有版本號不大於該版本的指令碼。再按照版本號從小到大,逐個執行其餘指令碼。
##在SpringBoot專案使用Flyway
Flyway既支援使用客戶端command-lineclient命令列方式也支援JAVA API方式升級資料庫,本文只介紹JAVA API以Maven引入外掛方式的使用,更多方式可以檢視官網;
引入依賴
在start.spring.io上新建一個SpringBoot工程,引入資料庫驅動依賴等,同時引入Flyway的依賴,這個步驟比較簡單,不做過多說明(本文示例使用的是Mysql資料庫);
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.14.0</version><!-- 截至發稿前,官網最新版本是7.14.0 -->
</dependency>
新增Flyway配置
spring:
# 資料庫連線配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/xukj_flyway?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: flyway
password: xxx
flyway:
# 是否啟用flyway
enabled: true
# 編碼格式,預設UTF-8
encoding: UTF-8
# 遷移sql指令碼檔案存放路徑,預設db/migration
locations: classpath:db/migration
# 遷移sql指令碼檔名稱的字首,預設V
sql-migration-prefix: V
# 遷移sql指令碼檔名稱的分隔符,預設2個下劃線__
sql-migration-separator: __
# 遷移sql指令碼檔名稱的字尾
sql-migration-suffixes: .sql
# 遷移時是否進行校驗,預設true
validate-on-migrate: true
# 當遷移發現資料庫非空且存在沒有後設資料的表時,自動執行基準遷移,新建schema_version表
baseline-on-migrate: true
建立SQL指令碼
專案建立以後,在src/resources下有 db/migration(或db.migration)目錄,在其中建立對應的SQL檔案,基於約定由於配置的原則,不同的型別透過檔案命名方式進行區分
Flyway對資料庫的所有更改都稱為遷移;版本遷移(Versioned Migrations)以V開頭,只會執行一次;回退遷移(Undo Migrations)以U開頭,執行一旦發生破壞性更改,就會很麻煩,專案中一般不用;可重複執行遷移(Repeatable Migrations)以R開頭,每次修改後都會重新執行。
總結如下:
-
僅需要被執行一次的SQL命名以大寫的"V"開頭,後面跟上"0~9"數字的組合,數字之間可以用“.”或者下劃線"_"分割開,然後再以兩個下劃線分割,其後跟檔名稱,最後以.sql結尾。比如,V2020.00.000_1 create_table.sql,V202001.00.000_2 insertTable.sql,V2.1.5__create_table.sql。
-
可重複執行的SQL,則以大寫的“R”開頭,後面再以兩個下劃線分割,其後跟檔名稱,最後以.sql結尾。比如,R addTable.sql,R update_user.sql。
-
版本號需要唯一,否則Flyway執行會報錯;如果V__指令碼.sql,已經執行過了,不能修改裡面的內容,再次執行Flyway就會報錯。R——指令碼.sql,如有變化可以執行多次。
-
V開頭的SQL執行優先順序要比R開頭的SQL優先順序高。
如下,我們準備了三個指令碼,分別為:
1、V2020.00.000_1__create_table.sql,程式碼如下,目的是建立一張表,且只執行一次
CREATE TABLE `test_flyway_table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`time` datetime NOT NULL COMMENT '建立時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、V202001.00.000_2__insertTable.sql,程式碼如下,目的是往表中插入一條資料,且只執行一次
INSERT INTO `test_flyway_table` VALUES ('1', '2021-06-28 17:48:48');
3、R__addTable.sql,程式碼如下,目的是每次啟動如果有變化,則執行一次
update `test_flyway_table` set time = '2021-08-23 17:48:48' where id =1;
對應目錄截圖如下:
執行
按照上面配置完成,已經足夠我們開始執行了,此時,我們第一次啟動專案,如果配置沒有錯誤,執行截圖如下:
此時,我們重新整理資料庫,可以看到Flyway的歷史記錄表已經生成並插入了三個版本的記錄:
而且,表也已經建立好了並有一條資料:
此時不做任何改變,重啟程式,日誌如下:
日誌顯示錶沒有變化,不做變更,檢視兩張表的內容也無變化。
如果我們修改V202001.00.000_2__insertTable.sql指令碼,重啟程式,就會報錯,提示資訊如下:
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 202001.00.000.2
-> Applied to database : 1190158040
-> Resolved locally: 843339817. Either revert the changes to the migration, or run repair to update the schema history.
如果我們修改R__addTable.sql指令碼,重啟程式,指令碼會再次執行,並且Flyway的歷史記錄表也會增加本次執行的記錄。
Flyway的執行效率
為了驗證Flyway專案資料庫迭代了較久時間,積累了幾百個Sql以後是否會拖慢專案的啟動速度?進行了一個對照組試驗:
場景(sql檔案控制在10K以內) | 執行平均時長(單位:秒) |
---|---|
放1個已經被執行過的SQL指令碼,反覆啟動專案 | 11.1 |
放25個已經被執行過的SQL指令碼,反覆啟動專案 | 11.4 |
放50個已經被執行過的SQL指令碼,反覆啟動專案 | 11.6 |
放100個已經被執行過的SQL指令碼,反覆啟動專案 | 12.19 |
指令碼在歷史記錄表中有記錄,即使有幾百條SQL指令碼,每次專案啟動只執行單次迭代的指令碼,所以耗時主要來源於兩個方面:
-
Flyway依次讀取指令碼中內容時的IO開銷;
-
Flyway計算指令碼checksum值的演算法開銷;
對於IO開銷而言,每個指令碼如果不是涉及大量的資料變更,只是表結構的變更,指令碼的大小都非常小,可以不考慮.事實上Flyway也不適合大量的資料變更時使用,因此IO開銷對啟動耗時的增量基本可以忽略
場景 | 執行平均時長(單位:毫秒) |
---|---|
讀取一個超大檔案,約1M,並進行計算,反覆執行多次 | 48 |
讀取一個正常大小的SQL指令碼,約10K,並進行計算,反覆執行多次 | 4 |
由此可見,即便是有上百個正常大小的sql,計算checksum值也不會耗費太多的時間,基本都可以在1秒內完成,所以接入Flyway後也不必擔心會有歷史包袱。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70001864/viewspace-2847796/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用Flyway來管理資料庫版本資料庫
- Flyway版本化管理資料庫指令碼資料庫指令碼
- Spring Boot Flyway管理資料庫版本 - josdemSpring Boot資料庫
- Spring Boot 2 實戰:使用 Flyway 管理你資料庫的版本變更Spring Boot資料庫
- 資料庫版本管理工具Flyway應用資料庫
- Flyway, 資料庫Schema管理利器資料庫
- 【jOOQ中文】3. 資料庫版本管理工具Flyway資料庫
- 使用Java和Flyway進行資料庫版本控制Java資料庫
- Spring Boot 2.x基礎教程:使用Flyway管理資料庫版本Spring Boot資料庫
- 更簡單靈活地管理 Ruby 版本
- ODC 3.4.0 現已上線,讓資料庫開發更簡單資料庫
- Spring Boot 整合 Flyway 實現資料庫版本控制Spring Boot資料庫
- 資料庫遷移神器——Flyway資料庫
- 智簡魔方DCIM系統如何讓資料中心管理變得更簡單
- Django學習(四)表單,讓資料庫更強大Django資料庫
- KubeBlocks v0.8.0 釋出!Component API 讓資料庫引擎組裝更簡單!BloCAPI資料庫
- Tvori推出2.0版本,讓VR動畫製作更簡單VR動畫
- 嘗試讓查詢更簡單
- 2021 OceanBase 年度報告 | 用技術讓海量資料的管理和使用更簡單!
- 2021 OceanBase 年度報告 | 用技術讓海量資料的管理和使用更簡單
- windows下node更換版本(簡單操作)Windows
- Coding Monthly | 讓開發更簡單!
- 2022 OceanBase 年度報告|用技術讓海量資料的管理和使用更簡單!
- 當 dbt 遇見 TiDB丨高效的資料轉換工具讓資料分析更簡單TiDB
- 高效規範的 圖紙管理解決方案,讓圖紙文件管理更簡單
- 讓資料視覺化變得簡單 – JavaScript 圖形庫視覺化JavaScript
- DataGrip 2023:讓資料庫開發變得更簡單、更高效 mac/win啟用版資料庫Mac
- 讓動畫實現更簡單,Flutter 動畫簡易教程!動畫Flutter
- 4 個概念,1 個動作,讓應用管理變得更簡單
- 做好供應商關係管理,讓企業採購交易更簡單
- 讓 Android 應用提交更簡單——用Worktile管理Android ReleaseAndroid
- go-mongox:簡單高效,讓文件操作和 bson 資料構造更流暢Go
- Minitab 2021:讓資料分析變得更簡單,更直觀 win版
- 簡單好用的資料庫管理:DBeaverEE mac啟用版資料庫Mac
- CSS 文件流技巧,讓佈局更簡單CSS
- 讓服務呼叫更簡單 - Caller.HttpClientHTTPclient
- 使用原生 cookieStore 方法,讓 Cookie 操作更簡單Cookie
- Serverless + AI 讓應用開發更簡單ServerAI