一、 flyway介绍
1、简介
Flyway是一个开源的数据库迁移工具,它可以帮助开发团队轻松管理数据库的变更和版本控制。
使用Flyway,你可以将数据库的变更(如创建表、添加列、修改数据等)作为一系列迁移脚本进行管理。每个迁移脚本都有一个唯一的版本号,Flyway会按照版本号的顺序依次执行这些脚本,从而将数据库迁移到所需的状态。
2、flyway版本 与 MySQL 版本 对应关系
- Flyway 6.x.x:支持MySQL 5.5及以上版本
- Flyway 7.x.x:支持MySQL 5.6及以上版本
- Flyway 8.x.x:支持MySQL 5.7及以上版本
- Flyway 8.2.x:支持MySQL 8.0及以上版本
3、脚本命名方式
序号 | 类型 | 内容 | 格式 | 备注 |
---|---|---|---|---|
1 | 版本迁移 | 以V开头,只会执行一次 | V{版本号(可以用点或下划线)}{分隔符(默认:__)}{描述}.sql | |
2 | 回退迁移 | 以U开头 | U{版本号(可以用点或下划线)}{分隔符(默认:__)}{描述}.sql | 执行一旦发生破坏性更改,会很麻烦,项目中一般不用。 |
3 | 可重复执行迁移 | 以R开头 | R{分隔符(默认:__)}{描述}.sql |
注:V开头的SQL执行优先级要比R开头的SQL优先级高。
二、为什么要使用flyway
-
版本控制:Flyway 允许开发团队将数据库结构的变化纳入版本控制系统,就像管理代码一样。每个数据库迁移都被视为一个独立的版本,并且可以追踪和管理每个版本的变化。这样可以确保团队成员对数据库结构的变更进行跟踪,并轻松地回滚或迁移到特定的版本。
-
自动化迁移:Flyway 可以自动检测并应用未应用的数据库迁移。当应用程序启动时,Flyway 会检查数据库中是否存在未应用的迁移,然后按照定义的顺序逐个应用这些迁移。这样可以简化数据库结构的更新过程,并确保每个开发人员、测试环境和生产环境中的数据库保持一致。
-
跨多个环境的一致性:使用 Flyway 可以确保开发、测试和生产环境中的数据库结构保持一致。每个环境都可以使用相同的迁移脚本,并在部署过程中自动应用这些脚本。这样可以减少人为错误和环境差异导致的问题,并提高应用程序的可靠性和稳定性。
-
跨数据库平台支持:Flyway 支持多种主流数据库平台,包括 MySQL、PostgreSQL、Oracle、SQL Server 等。这使得开发团队可以在不同的数据库上使用相同的迁移脚本和工作流程,而无需为每个数据库平台单独编写和维护迁移脚本。
三、Flyway 的工作方式
Flyway 的工作方式可以概括为以下几个步骤:
-
创建迁移脚本:开发团队使用 SQL 脚本编写数据库结构的变更脚本,通常以版本号命名,例如 V1__create_table.sql、V2__add_column.sql 等。这些脚本描述了数据库的初始结构以及每个版本之间的变更。
-
配置和初始化:在应用程序中配置 Flyway,指定数据库连接信息、迁移脚本的位置等。当应用程序启动时,Flyway 会自动初始化并连接到指定的数据库。
-
执行迁移:Flyway 检查数据库中的 flyway_schema_history 表,该表用于记录已应用的迁移信息。它会对比 flyway_schema_history 表中的记录和迁移脚本文件夹中的脚本,确定未应用的迁移。
-
应用迁移脚本:Flyway 依照版本号顺序逐个应用未应用的迁移脚本。它会执行 SQL 脚本来创建表、修改表结构、插入数据等操作。每个迁移脚本都会在 flyway_schema_history 表中记录执行的信息,包括版本号、描述、执行时间等。
-
数据库版本控制:每次应用迁移脚本后,Flyway 会更新 flyway_schema_history 表,标记已应用的迁移。这样可以跟踪数据库的版本历史,确保每个迁移只被应用一次。
-
验证和回滚:在应用迁移脚本后,Flyway 可以进行验证,检查数据库结构是否与期望的一致。如果验证失败,Flyway 将抛出异常并停止应用程序的启动。此外,Flyway 还支持回滚操作,可以撤销已应用的迁移。
-
集成到开发流程:Flyway 可以与构建工具(如 Maven、Gradle)和持续集成系统(如 Jenkins)集成,使数据库迁移成为开发流程的一部分。这样可以实现自动化的数据库迁移,并与应用程序的构建和部署过程无缝集成
通过以上步骤,Flyway 实现了数据库结构的版本控制和自动化迁移,确保开发团队能够轻松管理和维护数据库的演变过程,同时提高应用程序的可靠性和可维护性。
四、在spring boot中使用
1、在pom中引入依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
2、在application.yml配置
flyway:
# 是否启用flyway
enabled: true
# 编码格式,默认UTF-8
encoding: UTF-8
# 迁移sql脚本文件存放路径,默认db/migration
locations: classpath:db/migration
# 迁移sql脚本文件名称的前缀,默认V
sql-migration-prefix: V
# 迁移sql脚本文件名称的分隔符,默认2个下划线__
sql-migration-separator: __
# 迁移sql脚本文件名称的后缀
sql-migration-suffixes: .sql
# 迁移时是否进行校验,默认true
validate-on-migrate: true
# 当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表V1_2020
3、在resources新建文件夹db/migration
4、添加需要运行的sql脚本。sql脚本的命名一定要规范,否则运行flyway会报错
注:命名规则:
- 仅需要被执行一次的SQL命名以大写的"V"开头,V+版本号(版本号的数字间以”.“或”_“分隔开)+双下划线(用来分隔版本号和描述)+文件描述+后缀名。例如: V20201100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql 。
- 可重复运行的SQL,则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。(不推荐使用)比如: R__truncate_user_dml.sql
5、启动spring boot项目
在控制台可以看到相关日志打印,并在数据库中查看到已经创建好的表和相关记录变更
6、maven插件的使用
以上步骤中,每次想要migration都需要运行整个springboot项目,并且只能执行migrate一种命令,其实flyway还是有很多其它命令的。maven插件给了我们不需要启动项目就能执行flyway各种命令的机会
(1)引入插件
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>7.15.0</version>
<configuration>
<url>jdbc:mysql://loclhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
</url>
<user>root</user>
<password>dwchd2020</password>
<driver>com.mysql.cj.jdbc.Driver</driver>
</configuration>
</plugin>
(2)插件命令说明
-
baseline
对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。 -
clean
清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。 -
info
用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。 -
repair
repair操作能够修复metaData表,该操作在metadata出现错误时很有用。 -
undo
撤销操作,社区版不支持。 -
validate
验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。 -
migrate
将未应用的迁移脚本应用到目标数据库中
注意事项
- flyway执行migrate必须在空白的数据库上进行,否则报错
- 对于已经有数据的数据库,必须先baseline,然后才能migrate。
- clean操作是删除数据库的所有内容,包括baseline之前的内容。
- 尽量不要修改已经执行过的SQL,即便是R开头的可反复执行的SQL,它们会不利于数据迁移。
- 当需要做数据迁移的时候,更换一个新的空白数据库,执行下migrate命令,所有的数据库更改都可以一步到位地迁移过去。