数据库版本控制之flyway
一、Flyway
1.1 介绍
Flyway 是用来进行数据库的版本控制,帮助用户完成数据库迁移的工作。使用 Flyway ,用户可以从任意一个数据库版本迁移到最新版本,简单而且有效。
1.3 使用场景
- 适合团队共同维护数据库结构,而不是将数据库版本维护工作统一交给一个人处理。
- 方便为不同的环境,维护数据库版本
1.4 工作原理
1) 在数据库中维护一张名为 flyway_schema_history 的元数据表,里面存储着已执行的各个版本的记录;
2) 扫描系统文件或者应用的类路径中特定的文件,它们可以由 SQL 或 Java 编写。
3) 基于文件的版本号进行排序
4) 与元数据表进行校验,如果版本号低于或等于当前标记的版本,它们将被忽略,高于标记的文件将会被执行并更新元数据表
1.5 运行方式
- 基于命令行模式,用户从官网下载工具包,进行一些必要的配置,就可以通过命令行使用其功能。
- 基于Java API,用户可以将 Flyway 提供的第三方包加入 classpath,通过 Flyway 提供的 API 来使用其功能。
- 基于 Maven 或 Gradle,用户可以通过配置插件,运行 mvn 或 gradle 命令来使用其功能。
1.6 脚本文件命名规则
V<VERSION>__<NAME>.sql
- 大写字母 V 开头
- 版本号,小版本号可以用下划线隔开,如 2_1
- 脚本名称,脚本名称和版本号之间以两个下划线隔开
- 文件后缀为 .sql
二、 基于 SpringBoot 下使用 flyway
2.1 引入 pom 依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>6.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.2 创建脚本文件
flyway 默认存放路径是 src/main/resources/db/migration
这里我们采用自定义的目录
src/main/resources/db/dev/v1
在目录中新建 V1_1__createTable.sql 文件,内容如下:
CREATE TABLE `sys_user` (
`user_id` bigint(21) NOT NULL COMMENT '用户编码',
`user_name` varchar(50) DEFAULT NULL COMMENT '用户名',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.3 配置应用属性
在 application.yml 文件中填写上数据库和 flyway 相关配置:
spring:
# flyway 相关配置
flyway:
# 启用 flyway
enabled: true
# 字符集编码
encoding: utf-8
# 脚本文件存放地址,默认存放地址为 classpath:db/migration
locations: classpath:db/dev
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/flyway_test?serverTimezone=UTC&useUnicode=true&useSSL=false&useUnicode=true&characterEncoding=utf8
username: root
password: sa000
2.4 启动应用
查看数据库,发现新增了如下两张表:
查看 flyway_schema_history 表:
可以看到执行的版本记录
三、 flyway 遇到的问题
3.1 在非空数据库下执行
默认情况下在非空数据库下执行,会抛出异常:
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) `test` but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
配置属性baseline-on-migrate 为 true 即可:
spring:
flyway:
# 在没有元数据表的情况下,针对非空Schema执行迁移时是否自动调用基线。 (默认值:false)
baseline-on-migrate: true
# 配合 baseline-on-migrate 使用,否则 V1 的版本不会执行
baseline-version=0: