背景

在项目开发中,程序代码可以使用svn或者git来管理版本。但是在数据库开发中,版本的控制一直是个比较头疼的问题,通过调研,spring的官方支持flyway和liquibase的数据库版本管理工具

flyway

flyway 是一个敏捷工具,用于数据库的移植。采用 Java 开发,支持所有兼容 JDBC 的数据库。

主要用于在你的应用版本不断升级的同时,升级你的数据库结构和里面的数据

https://link.juejin.cn/?target=https%3A%2F%2Fflywaydb.org%2F
支持的数据库:
Oracle、SQL Server、DB2、MySQL、Aurora MySQL、MariaDB、Percona XtraDB群集、PostgreSQL、Aurora PostgreSQL、Redshift、CockroachDB、SAP HANA、Sybase ASE、Informix、H2、HSQLDB、Derby、SQLite、Firebird

工作原理

flyway通过历史记录表(flyway_schema_history)来记录版本历史。每次随项目启动时将会自动扫描在resources/db/migration下的文件并查询flyway_schema_history判断是否为新增文件。如果是新增的文件,则执行该迁移文件。如果不是,则忽略

flyway_schema_history 表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE `flyway_schema_history` (
`installed_rank` int(11) NOT NULL,
`version` varchar(50) DEFAULT NULL,
`description` varchar(200) NOT NULL,
`type` varchar(20) NOT NULL,
`script` varchar(1000) NOT NULL,
`checksum` int(11) DEFAULT NULL,
`installed_by` varchar(100) NOT NULL,
`installed_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`execution_time` int(11) NOT NULL,
`success` tinyint(1) NOT NULL,
PRIMARY KEY (`installed_rank`),
KEY `flyway_schema_history_s_idx` (`success`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

第一次执行:在一个空数据库上执行时。会创建一个flyway_schema_history。这个表用来记录和追踪数据库版本的状态,然后flyway会扫描文件系统或者项目下classpath路径下的数据库文件

再次执行:flyway会再次扫描迁移文件,然后将迁移文的版本号与历史记录表中的版本号进行对比。flyway会忽略版本号小于等于表中当前最大版本的迁移文件,剩余待执行迁移文件会按版本号升序执行。(译者注:并非真正忽略,而是会校验checksum值是否一致,以此来保证历史版本文件未被篡改。)

SpringBoot集成flyway

1 添加依赖

这里可以不用指定flyway的版本号,因为springboot父类依赖中已经指定了版本号, 如果执行可能会包版本冲突

1
2
3
4
5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

2 添加配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 开启
spring.flyway.enabled=true
# 禁止清理数据表
spring.flyway.clean-disabled=true
# 版本控制信息表名,默认 flyway_schema_history
spring.flyway.table=flyway_schema_history
# 是否允许不按顺序迁移
spring.flyway.out-of-order=false
# 如果数据库不是空表,需要设置成 true,否则启动报错
spring.flyway.baseline-on-migrate=true
# 与 baseline-on-migrate: true 搭配使用,小于此版本的不执行
spring.flyway.baseline-version=0
# 使用的schema 这里可以不用设置,因为不设置就使用使用spring连接数据的地址和数据库
spring.flyway.schemas=test
#数据库连接
#spring.flyway.url=
#数据库用户名
#spring.flyway.user=
#数据库密码
#spring.flyway.password=
# 执行迁移时是否自动调用验证
spring.flyway.validate-on-migrate=true

实际配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/renren-fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username:
password:
flyway:
baseline-on-migrate: true
enabled: true
locations: classpath:db/migration
baseline-version: 1

3 添加配置文件

在resources目录下创建db/migration文件夹

在db/migration目录下创建版本迁移文件 V1__initial.sql

命名规则

在src/resources下创建 db/migration目录,在其中创建对应的SQL文件,其中又分为不同的文件类型,基于约定由于配置的原则,通过文件命名方式进行区分

版本迁移以V开头,只会执行一次;回退迁移以U开头,一般不使用;可重复执行迁移以R开头,每次修改后都会重新执行

upload successful

参考