为什么需要数据库版本控制
在真实的项目开发中,我们一般有三套环境:开发、测试、生产。在开发阶段我们一般都是在开发环境中进行操作,项目开发肯定不止一个人,在开发的过程中,我们肯定会对数据库的库表进行一些修改操作。并且这些操作需要同步到这三套环境中。但是多人协同,人为操作难免会出现疏忽,有时候修改了开发环境忘记了去修改其他环境。很多情况下都需要对数据库的变化做跟踪,以便于我们回退到某个版本。因此我们需要有这样一个工具来帮助我们管理数据库版本,做好各个环境同步更新。
为什么选择Flyway
现在比较常用的数据库版本管理工具有Flyway和Liquibase。Spring Boot提供了这两者的内建支持,可以很快应用到产品中。
使用Flyway的好处在于使用简单,直接书写我们比较熟悉的sql脚本即可,不需要进行额外的学习。Liquibase的优点在于它能跨平台、跨库,但是需要我们花时间去学习他的脚本编写规则。如果你的项目中没有跨数据库的需要,那么flyway完全够用了。
Flyway的工作模式
flyway在项目运行的时候会判断你的数据库中是否存在flyway_schema_history表,如果没有就会创建。这个表主要用于记录数据库的状态,Flyway的版本控住主要也是依赖这张表的。
当flyway_schema_history这张表存在,。当检测到你有新的版本需要迁移的时候,Flyway会逐一对比flyway_schema_history表中的已存在的版本记录,如果有未应用的Migrations,Flyway会获取这些Migrations并按版本号次序迁移到数据库中。

应用每个迁移时,flyway_schema_history表将相应更新:

flyway在升级数据库的时候,会检查已经执行过的版本对应的脚本是否发生变化,包括脚本文件名,以及脚本内容。如果flyway检测到发生了变化,则抛出错误,并终止升级。
如果已经执行过的脚本没有发生变化,flyway会跳过这些脚本,依次执行后续版本的脚本,并在记录表中插入对应的升级记录。
所以,flyway总是幂等的,而且可以支持跨版本的升级。
Migrations就是我们用SQL编写的脚本。为了让我们编写的SQL脚本生效,还需要按照Flyway指定的方式进行命名。

- Prefix:
V代表版本化,U代表撤销,R代表可重复迁移。 - Version: 带点或下划线的版本,可以随意分隔多个部分(不适合重复迁移)。
- Separator:
__(两个下划线) - Description: 下划线或空格分隔单词
- Suffix:
.sql
如何使用
1、添加依赖
1 | <dependency> |
2、配置application.yml文件
1 | spring: |
flyway下没有配置url、user、password的话将会使用springboot的数据源。
3、在db.migration包下新建V1__initialization_table.sql文件。
1 | DROP TABLE IF EXISTS user; |
flyway脚本默认放在classpath:/db/migration目录下面,如果想换位置,可以自定义一个位置spring.flyway.locations即为脚本存放的位置。
4、开始验证
目前只有test库中没有任何表:

我们开始启动项目看看:

通过日志信息,我们可以看到已经迁移成功了,我们去数据库看看。

表结构:

现在我们来给user表新增一个字段试试。
V1.1__addField_col.sql
1 | alter table user add mail varchar(128) comment '用户邮箱'; |
运行项目看看

表结构:
