數據庫遷移搞炸了!竟然沒用這款開源神器的鍋? 摘要 Flyway簡介 相關概念 命令行工具 Maven插件 結合SpringBoot使用 總結 參考資料

摘要

當我們的應用升級時往往會伴隨着數據庫表結構的升級,此時就需要遷移數據庫的表結構。一般我們會使用工具或者腳本來實現,手動操作畢竟有一定風險,要是能在應用啓動時自動升級數據庫表結構就好了!Flyway正是這麼一款工具,通過Flyway和SpringBoot結合使用,在應用啓動時就可以自動升級數據庫表結構,非常方便,推薦給大家!

Flyway簡介

Flyway是一款數據庫遷移工具,它讓數據庫遷移變得更加簡單。它能像Git一樣對數據庫進行版本控制,支持命令行工具、Maven插件、第三方工具(比如SpringBoot)等多種使用方式。

Flyway具有如下特點:

  • 簡單:使用和學習簡單,通過不同版本的SQL腳本實現數據庫遷移。
  • 專業:專注於數據庫遷移功能,你無需擔心有任何問題。
  • 功能強大:支持多種數據庫,擁有大量的第三方工具,支持CI/DI。

相關概念

工作原理

使用Flyway時我們需要編寫好數據庫遷移的SQL腳本,比如 V1__Initial_Setup.sql中初始化了三種表,V2__First_Changes.sql中又新增了兩種表。Flyway會創建flyway_schema_history表,用於存儲這些SQL腳本的執行情況,從而對數據庫進行版本控制。當我們使用Flyway進行數據庫遷移時,Flyway會根據flyway_schema_history表中的記錄,自行決定需要執行哪些SQL腳本,從而實現數據庫遷移。

腳本命名規範

在創建Flyway的SQL腳本時,有些命名規範需要遵守,這些命名規範決定了Flyway執行腳本的順序和方式,可以先參考下面的示意圖。

爲了能被Flyway正確執行,SQL遷移腳本需要遵循如下規範:

  • Prefix(前綴):V表示有版本號的數據庫遷移,U表示一些數據庫版本的回滾,R表示可重複執行的數據庫遷移;
  • Version(版本號):Flyway會按照版本號的大小順序來執行數據庫遷移腳本;
  • Separator(分隔符):命名時使用雙下劃線分隔符;
  • Description(描述):用於描述該遷移腳本的具體操作說明;
  • Suffix(後綴):表示.sql文件。

相關命令

  • migrate:數據庫遷移命令,會根據設置好的SQL腳本直接將數據庫表升級至最新版本。
  • clean:刪除數據庫中所有的表,千萬別在生產環境上使用。
  • info:打印所有關於數據庫遷移的詳細信息和狀態信息。
  • validate:驗證數據庫遷移是否可用。
  • undo:對數據庫遷移進行回滾操作。
  • baseline:以現有數據庫爲基準,創建flyway_schema_history表,大於基準版本的數據庫遷移纔會被應用。
  • repair:修復flyway_schema_history表。

命令行工具

使用Flyway實現數據遷移有多種方式,我們先通過命令行工具的方法來體驗下Flyway的使用。

  • 下載完成後進行解壓,解壓完成後目錄結構如下;
  • 修改Flyway的配置文件/conf/flyway.conf,修改下數據庫配置即可;
flyway.url=jdbc:mysql://localhost:3306/flyway?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai 
flyway.user=root
flyway.password=root
  • 在/sql目錄下添加SQL執行腳本,這裏添加創建ums_admin表的執行腳本V1.0.1__Create_ums_admin_table.sql;
CREATE TABLE `ums_admin`
(
  `id`          bigint(20) NOT NULL AUTO_INCREMENT,
  `username`    varchar(64)  DEFAULT NULL,
  `password`    varchar(64)  DEFAULT NULL,
  `icon`        varchar(500) DEFAULT NULL COMMENT '頭像',
  `email`       varchar(100) DEFAULT NULL COMMENT '郵箱',
  `nick_name`   varchar(200) DEFAULT NULL COMMENT '暱稱',
  `note`        varchar(500) DEFAULT NULL COMMENT '備註信息',
  `create_time` datetime     DEFAULT NULL COMMENT '創建時間',
  `login_time`  datetime     DEFAULT NULL COMMENT '最後登錄時間',
  `status`      int(1)       DEFAULT '1' COMMENT '帳號啓用狀態:0->禁用;1->啓用',
  PRIMARY KEY (`id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 8
  DEFAULT CHARSET = utf8 COMMENT ='後臺用戶表';
  • 使用flyway migrate命令進行數據遷移,此時我們會發現需要先使用flyway baseline命令創建保存遷移記錄的表flyway_schema_history纔行;
  • 先使用flyway baseline命令,再使用flyway migrate命令,命令行會輸出執行成功的信息;
  • 在\sql目錄下添加SQL執行腳本,給ums_admin表添加一些數據,執行腳本爲V1.0.2__Add_ums_admin.sql;
INSERT INTO ums_admin (username, PASSWORD, email, nick_name, STATUS)
VALUES ('test', '123456', '[email protected]', '測試賬號', 1);
INSERT INTO ums_admin (username, PASSWORD, email, nick_name, STATUS)
VALUES ('macro', '123456', '[email protected]', '普通賬號', 1);
INSERT INTO ums_admin (username, PASSWORD, email, nick_name, STATUS)
VALUES ('andy', '123456', '[email protected]', '普通賬號', 1);
  • 我們可以使用flyway info命令查看flyway_schema_history表中的數據遷移記錄,可以發現1.0.2版本的更新還處於Pending狀態,使用flyway migrate命令後變爲Success;
  • 我們可以創建可重複執行的SQL腳本,通常可以用來創建視圖、存儲過程、函數等,比如基於ums_admin表創建一個視圖,執行腳本爲R__Ums_admin_view.sql;
CREATE
  OR REPLACE VIEW ums_admin_view AS
SELECT username,
       PASSWORD,
       email
FROM ums_admin;
  • 使用flyway migrate命令可以重複執行(當R開頭的腳本有變更時),該腳本會在所有V開頭的腳本執行完成後執行;
  • Flyway的回滾機制需要依賴SQL腳本,這裏創建U1.0.1__Create_ums_admin_table.sql和U1.0.2__Add_ums_admin.sql兩個回滾腳本;
# U1.0.1__Create_ums_admin_table.sql
DROP TABLE ums_admin
# U1.0.2__Add_ums_admin.sql
DELETE FROM ums_admin;
  • 使用flyway undo命令可以執行回滾,很遺憾的是社區版本不支持回滾,看樣子數據庫升級之前還是得通過工具做好備份纔行!

Maven插件

Flyway也提供了Maven插件,插件所支持功能與命令行工具基本一致。

  • 想要在Maven項目通過插件使用Flyway,首先需要在pom.xml中添加Flyway的插件並配置好數據庫連接信息;
<!--Flyway的Maven插件-->
<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>7.3.2</version>
    <configuration>
        <url>jdbc:mysql://localhost:3306/flyway?serverTimezone=Asia/Shanghai</url>
        <user>root</user>
        <password>root</password>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>
    </dependencies>
</plugin>
  • 在resouce目錄下創建db\migration目錄,將數據庫升級使用的SQL腳本放入進去;
  • Flyway的Maven插件支持如下幾種命令;
  • 雙擊flyway:info命令使用,輸出如下內容,此方式與命令行工具使用基本沒啥區別。
[INFO] --- flyway-maven-plugin:7.3.2:info (default-cli) @ mall-tiny-flyway ---
[INFO] Flyway Community Edition 7.3.2 by Redgate
[INFO] Database: jdbc:mysql://localhost:3306/flyway (MySQL 5.7)
[INFO] Schema version: 1.0.2
[INFO] 
[INFO] +------------+---------+------------------------+----------+---------------------+----------+
| Category   | Version | Description            | Type     | Installed On        | State    |
+------------+---------+------------------------+----------+---------------------+----------+
|            | 1       | << Flyway Baseline >>  | BASELINE | 2020-12-24 11:17:35 | Baseline |
| Versioned  | 1.0.1   | Create ums admin table | SQL      | 2020-12-24 11:17:42 | Success  |
| Versioned  | 1.0.2   | Add ums admin          | SQL      | 2020-12-24 11:33:40 | Success  |
| Repeatable |         | Ums admin view         | SQL      | 2020-12-24 11:33:40 | Success  |
+------------+---------+------------------------+----------+---------------------+----------+

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.076 s
[INFO] Finished at: 2020-12-24T14:28:16+08:00
[INFO] Final Memory: 28M/286M
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0

結合SpringBoot使用

由於SpringBoot官方已經支持了Flyway,所以Flyway結合SpringBoot使用非常簡單!

  • 首先在pom.xml中添加Flyway相關依賴,注意無需添加Flyway的版本號:
<!--Flyway相關依賴-->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
  • 修改配置文件application.yml,對數據源和Flyway進行配置;
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/flyway?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  flyway:
    # 啓用Flyway功能
    enabled: true
    # 禁用Flyway的clean命令,使用clean命令會刪除schema下的所有表
    clean-disabled: true
    # 設置Flyway的SQL腳本路徑
    locations: classpath:db/migration
    # 設置版本信息控制表名稱,默認flyway_schema_history
    table: flyway_schema_history
    # 在執行migrate命令時需要有flyway_schema_history表,通過baseline命令可以生成該表
    baseline-on-migrate: true
    # 指定baseline版本號,低於該版本的SQL腳本在migrate是不會執行
    baseline-version: 1
    # 設置字符編碼
    encoding: UTF-8
    # 不允許不按順序遷移
    out-of-order: false
    # 設置Flyway管控的schema,不設置的話爲datasourcel.url中指定的schema
    schemas: flyway
    # 執行migrate時開啓校驗
    validate-on-migrate: true
  • 最後直接運行SpringBoot應用,即可自動創建好對應的數據庫,控制檯會輸出如下信息。
2020-12-24 14:38:15.659  INFO 10716 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 6.4.1 by Redgate
2020-12-24 14:38:15.898  INFO 10716 --- [           main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:mysql://localhost:3306/flyway (MySQL 5.7)
2020-12-24 14:38:15.972  INFO 10716 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 3 migrations (execution time 00:00.047s)
2020-12-24 14:38:15.988  INFO 10716 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table `flyway`.`flyway_schema_history` with baseline ...
2020-12-24 14:38:16.106  INFO 10716 --- [           main] o.f.core.internal.command.DbBaseline     : Successfully baselined schema with version: 1
2020-12-24 14:38:16.122  INFO 10716 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `flyway`: 1
2020-12-24 14:38:16.134  INFO 10716 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `flyway` to version 1.0.1 - Create ums admin table
2020-12-24 14:38:16.248  INFO 10716 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `flyway` to version 1.0.2 - Add ums admin
2020-12-24 14:38:16.281  INFO 10716 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `flyway` with repeatable migration Ums admin view
2020-12-24 14:38:16.314  INFO 10716 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 3 migrations to schema `flyway` (execution time 00:00.206s)

總結

對比手動升級數據庫表結構,使用Flyway自動升級更有優勢。使用Flyway可以在我們升級應用時同時升級數據庫,由於社區版本目前不支持數據庫回滾,升級前做好備份是很有必要的。

參考資料

官方文檔:https://flywaydb.org/documentation/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章