数据库版本控制:flywaydb
概念
Flyway 对数据库的所有更改都称为迁移。迁移可以是版本化的或可重复的。版本化迁移有两种形式:
常规
和撤消
。
默认情况下,版本化和可重复迁移都可以用SQL 或Java编写,并且可以由多个语句组成。Flyway 自动发现文件系统和 Java类路径上的迁移。
- 版本化迁移(Versioned migrations)
有一个版本、一个描述和一个校验和。版本必须是唯一的。该描述纯粹是提供信息,让您能够记住每次迁移的作用。校验和用于检测意外更改。版本化迁移是最常见的迁移类型。它们
只按顺序应用一次
。
⚠️ 可以通过提供具有相同版本的**撤消迁移(undo migration)**来撤消它们的影响。
- 可重复的迁移(Repeatable migrations)
有描述和校验和,但没有版本。它们不是只运行一次,而是在每次校验和更改时(重新)应用。
在单次迁移运行中,可重复迁移总是最后应用,在所有挂起的版本化迁移都已执行之后。可重复迁移按其描述的顺序应用。
版本化迁移
应用场景
- Creating/altering/dropping tables/indexes/foreign keys/enums/UDTs/… (创建/更改/删除表/索引/外键/枚举/UDT/…)
- Reference data updates (数据更新)
- User data corrections (用户数据更正)
版本号
任意数字格式:(整数)
如: 1、001、5.2、2021.12.13
撤销迁移
与常规版本化迁移相反。撤消迁移负责撤消具有相同版本的版本化迁移的影响。撤消迁移是可选的,不需要运行常规版本化迁移。
DELETE FROM brand WHERE name='DeLorean';
ALTER TABLE owner DROP driver_license_id;
DROP TABLE car;
⚠️
虽然撤消迁移的想法很好,但不幸的是它有时会在实践中失败。更可取的替代方法是:保持数据库与当前部署在生产中的所有代码版本之间的向后兼容性。
可重复迁移
有描述和校验和,但没有版本。它们不是只运行一次,而是在每次校验和更改时(重新)应用。
这对于管理数据库对象非常有用,这些对象的定义可以简单地在版本控制中的单个文件中维护。在单次迁移运行中,可重复迁移总是最后应用,在所有挂起的版本化迁移都已执行之后。可重复迁移按其描述的顺序应用。
应用场景
- (Re-)creating views/procedures/functions/packages/… (重新)创建视图/过程/函数/包/…
- Bulk reference data reinserts 批量引用数据重新插入
案例:
CREATE OR REPLACE VIEW blue_cars AS
SELECT id, license_plate FROM cars WHERE color='blue';
基于sql的迁移
迁移通常是用SQL编写的。这样可以轻松入门并利用任何现有的脚本、工具和技能。它使您可以访问数据库的全套功能,并且无需了解任何中间翻译层。
应用场景
- DDL 更改(表、视图、触发器、序列等的 CREATE/ALTER/DROP 语句)
- 简单的参考数据更改(参考数据表中的 CRUD)
- 简单的批量数据更改(常规数据表中的 CRUD)
sql文件命名
文件名由以下部分组成:
1. 前缀:V用于版本化(可配置), U用于撤消(可配置)和 R可重复迁移(可配置)
2. 版本:带有点或下划线的版本可以根据需要分隔多个部分(不适用于可重复迁移)
3. 分隔符:(__两个下划线)(可配置)
4. 描述:下划线或空格分隔单词
5. 后缀:.sql(配置)
- 版本化迁移
V1.0.7__add_new_tables_colums.sql
- 撤销迁移
U1.0.7__remove_colums.sql
- 可重复迁移
R__add_ functions.sql
springboot maven集成
- 添加相关pom.xml引用
<!--数据库版本控制-->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>8.2.1</version>
</dependency>
<!--数据库版本控制插件,可选-->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.2.1</version>
<configuration>
<url>jdbc:mysql://ip:3306/dbName?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true</url>
<user>xxx</user>
<password>xxx</password>
<!--数据库驱动-->
<driver>com.mysql.cj.jdbc.Driver</driver>
</configuration>
</plugin>
- 配置版本控制文件
创建迁移目录:src/main/resources/db/migration
- 设置相关配置
spring:
# 数据库版本控制
flyway:
# 是否开启flywaydb,默认 true
enabled: true
# 迁移脚本的位置,默认db/migration.
locations:
- "classpath:db/migration"
# 当发现校验错误时是否自动调用clean,默认false;谨慎使用,开启的话如果失败会清空schemas
# clean-on-validation-error: false
# 对执行前移时基准版本的描述
baseline-description: 基于1.0.6版本
# 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
baseline-on-migrate: true
# 开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
baseline-version: "1.0.6"
# 迁移时是否校验命名,默认false.
validate-migration-naming: true
# 迁移时是否校验,默认为true
validate-on-migrate: true
# 读取架构历史记录表时忽略丢失的迁移;默认 false
ignore-missing-migrations: true
# 是否混合迁移;默认:false
# mixed: false
# 允许“无序”运行迁移(默认值:false)
out-of-order: true
# 检查本地迁移文件是否存在;默认 true
check-location: false