一、概念解释
Flyway是一款开源的数据库迁移工具。可以相对简单的对数据库版本进行控制。
数据库版本文件:存放在版本文件目录下的sql脚本
二、工具使用
2.1 Springboot整合FlyWay
pom.xml文件引入依赖,将sql文件加入资源路径
<!-- flyway -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
...
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
2.2 application.yml当中配置
# flyway 配置信息
# 激活 flyway
spring.flyway.enabled=true
# 禁止清除数据库表:这个属性非常关键,它表示是否要清除已有库下的表,如果执行的脚本是 V1__xxx.sql,那么会先清除已有库下的表,然后再执行脚本,这在开发环境下还挺方便,但是在生产环境下就要命了,而且它默认就是要清除,生产环境一定要自己配置设置为 true。
spring.flyway.clean-disabled=true
# 如果指定 schema 包含了其他表,但没有 flyway schema history 表的话,设置为 true 后, flyway 将在需要 baseline 的时候, 自动执行一次 baseline
spring.flyway.baseline-on-migrate=true
# 指定 baseline 的版本号,缺省值为 1, 低于该版本号的 SQL 文件, migrate 的时候被忽略
spring.flyway.baseline-version=1
# sql文件目录,默认是 classpath:db/migration,如果有多个,用 , 隔开
spring.flyway.locations=classpath:db/migration
a. 配置好此二项后,在数据源配置无问题的情况下启动项目,数据库出现flyway_schema_history表即说明整合成功。
b. 工程启动时会根据当前版本依次执行比当前版本高的sql文件。
c. 可将数据库初始化数据库脚本作为基准版本,新项目第一次启动时执行,避免初始化数据库的额外工作。
三、分环境配置多套数据库版本文件示例
为解决不同生产环境部分sql版本文件不通用的问题
a. 配置文件目录结构

b. 主配置文件:application.properties

c. 生产环境1配置文件

四、FlyWay使用约定
4.1 数据库版本文件整体约定
一份数据库版本文件可包含多条操作数据库的sql命令(在一个数据库版本sql文件当中,可以写多个建表,插入数据sql)。
在一次提交中将所有需提交的数据库变更维护在同一个数据库版本文件中,无需也没有必要为每一条语句新增一个版本文件。如:在初始化的版本文件中包含了整套建表语句与初始化数据sql。
数据库版本文件使用新增的方式进行管理,提交svn后不允许修改(数据库sql版本不允许修改,若想更新数据库结构,需要新建一个sql数据文件)
该条约定的意思为若已添加某个数据库版本,此时又需要补充内容(或者纠错某些内容),不允许修改之前的版本文件,只能通过新增一份版本文件对数据库进行操作。可以结合svn版本管理进行理解,文件在提交后版本即固定,再想修改文件需要提交新版而旧版本的记录不变。
4.2 数据库版本文件命名约定
数据迁移文件相关注意事项:
-
文件存放位置:resources/db/migration
-
命名规则
- V[version]__[name].sql
- 名称中[version]和[name]之间是两个下划线
- [version]部分使用时间戳-年月日时分秒(例:20190625143301)
- [name]描述sql作用,使用“_”分隔
- 添加数据的sql文件版本[name]部分均需要加data_
-
注意事项:
- 每次对数据库表做出改动(通用改动,即所有部署环境都可变更的改动)均需要添加新版本的数据迁移文件
- 添加表字段只能用ALTER…ADD,绝不能删表重建!!!(删表重建会删除生产环境的所有表数据,严格禁止!!)
- 慎重执行删表,删数据相关sql
- 可将数据库初始化数据库脚本作为基准版本,新项目第一次启动时执行,避免初始化数据库的额外工作
- 服务启动时会根据当前版本依次执行比当前版本高的迁移文件
-
单一功能的版本文件[name]部分规则
- 纯数据操作的使用data_开头
- 新增数据使用_add结尾
- 修改数据使用_mod结尾
- 删除数据使用_del结尾
4.3 注意事项
当我们使用FlyWay执行数据库脚本之后,Flyway 还给创建了一个 flyway_schema_history 表,这个表用来记录数据库的更新历史。
这个表当中有记录的脚本,在下次项目启动后就不会在执行了,因为系统知道这个脚本已经执行过了,如果你还想让该 脚本再执行一遍,需要手动删除 flyway_schema_history 表中的对应记录,那么项目启动时,这个脚本就会被执行了。
所有的脚本,一旦执行了,就会在 flyway_schema_history 表中有记录,如果你不小心搞错了,可以手动从 flyway_schema_history 表中删除记录,然后修改 SQL 脚本后再重新启动(生产环境不建议)。
五、总结
flyway是用来做数据库版本管理的,一般主用用途是在运行程序的时候可以顺便生成表数据,
flyway管理的数据是哪些:一般我们将建表语句以及一些核心的数据通过flyway来管理
flyway运行的,对比的是flyway_schema_history 表记录和flyway的脚本文件,根据一定的算法进行对比
项目运行之后流程
在项目运行之后:
- 检测数据库当中的版本和项目当中版本是否一致
- 不一致,执行新脚本
- 一致
- 检测checksum是否一致
- 一致,不更新
- 不一致,说明已执行的flyway脚本给改动过,报错
注意事项如下:
所以我们在进行开发的过程当中,如果要对核心字段、核心数据进行更新,要通过flyway去执行!
因为,如果我们直接没有通过flyway去修改,而是通过sql或者直接修改的,那么在项目在其他的服务器上运行时,该字段还是之前的,不会修改!
注意:对于其他的数据,不需要维护在flyway当中,因为fly只是对表当中的数据、结构进行修改,对于未维护在flyway当中的数据,不会进行修改。
如果有多个flyway文件,在运行时会一个一个执行;如果在下次执行时,发现某个文件被改过了,则会报错
所以原则是执行后的文件如果要进行修改,不能再源文件上进行修改,需要新建文件进行修改。
注意:如果新加的版本日期小于之前的版本日期,则会报错;所以要先拉取代码,在更新脚本
flyway的checksum
官网已经说的很清楚,flyway获取flyway_schema_history中最新成功记录的版本号(基准version),与项目中db/migration文件夹中的文件version进行比对,当version大于基准version则执行。既然通过版本号就可以完成迁移前判断,那还需要checksum做什么呢?
其实我们在使用flyway的时候,需要养成这样一个习惯,一旦执行过的sql脚本就不要去修改,如果需要对已有数据表进行增删改的操作,应该新建一个脚本执行。但是对于修改已经执行过的sql脚本,flyway也有预防,那就是checksum。
每个sql脚本在执行前会将基本信息写入flyway_schema_history中,flyway会把每个脚本作为输入,通过某算法(不清楚)输出一个整数,这个数就是checksum,flyway在工作之前,会先基于baseline逐个脚本比对其数据库中的checksum值,如果计算结果不同,则会报mismatch的错误.