flyway快速入门
一、flyway是什么?
-
概念:Flyway 是一款开源的数据库版本管理工具。
-
数据库版本文件:存放在版本文件目录下的sql脚本(就是我们放在db.migration下的文件)
ps:flaway可以在命令行中使用,或者在java应用程序中引入(但是一般就是在项目中进行数据库版本迭代),可以相对简单的对数据库版本进行控制。
二、flyway使用目的
1. 使用原因:
在项目或产品中,很难一开始就把业务理清楚,所以很难一次性把数据库表设计好;(比如:我们现在建了一个表进行使用,过了一段时间甲方爸爸突然要求加个字段或者修个某个字段信息,这个时候我们就又得去修改数据库表;又过了几天甲方爸爸又说…如此折腾几下:干他!!!所以说数据表也会在周期内不断迭代)因此我们就需要在更新修改数据库的时候做记录,提交一次更新结果就记录下来,不同的人做不同的记录,这样就可以方便大家去看之间的版本情况;
2. 举个例子:
在协同开发时候,大家一般都是使用Git来对代码做版本控制,主要的目的一个是为了协调开发的方便性,再一个就是为了解决多人开发代码冲突和版本回退的问题。
解释一下什么是版本:
git:在git中,比如我写了一个业务逻辑,实现了某个功能,然后我就把这个项目push到git中去让测试或者其他人去联调使用。我们把这次提交就称为一个版本;后续我还会多次对代码进行修改,每一次提交就是一个版本;
flyway:同样的在flyway中,每一次提交的sql命令就是一个版本(创建、更改等等),而每一次的sql命令中会包含多个sql语句;
三、flyway工作原理
flyway工作流程如下:
- 启动一个项目,数据库连接建立成功后,Flyway开始自动运行;
- 初次使用时,flyway会创建一个 flyway_schema_history 表,用于记录sql执行记录;
- Flyway会扫描项目指定路径下(默认是 classpath:db/migration )的所有sql脚本,与 flyway_schema_history 表脚本记录进行比对
- 如果数据库记录执行过的脚本记录,与项目中的sql脚本不一致,Flyway会报错并停止项目执行。
- 如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。
四、flyway使用约定和命名规则
1. 数据库版本文件整体约定
- 一份数据库版本文件可包含多条操作数据库的sql命令。
在一次提交中将所有需提交的数据库变更维护在同一个数据库版本文件中,无需也没有必要为每一条语句新增一个版本文件。如:在初始化的版本文件中包含了整套建表语句与初始化数据sql。
- 数据库版本文件使用新增的方式进行管理,提交git后不允许修改。
该条约定的意思为若已添加某个数据库版本,此时又需要补充内容(或者纠错某些内容),不允许修改之前的版本文件,只能通过新增一份版本文件对数据库进行操作。可以结合svn版本管理进行理解,文件在提交后版本即固定,再想修改文件需要提交新版而旧版本的记录不变。
2. 数据库版本文件夹管理约定
- db/migration文件夹
此文件夹为通用版本文件目录,里面存放的数据库版本文件是所有环境所共有的,所有环境在启动时均会执行此文件夹下的数据库版本文件(较当前版本新的部分)。
- 特定环境文件夹均需放在db文件夹下,命名需与环境名称一致。
此文件夹下的数据库版本文件只会在相应环境下执行。
详细的配置如下 第8条所示:
3. 数据库版本文件命名约定
- 整体命名规则
整体规则为V[version]__[name].sql。名称中[version]和[name]之间是两个下划线,[version]部分使用时间戳-年月日时分秒_
(例:20190625143301),[name]描述sql作用,使用单词描述并使用“_”分隔。
举例:V20230804153701__today_creat(注意today之前是两个下划线)
-
单一功能的版本文件[name]部分规则
- 纯数据操作的使用data_开头
- 新增数据使用_add结尾
- 修改数据使用_mod结尾
- 删除数据使用_del结尾
-
复合功能的版本文件(版本文件中包含多种不同的类型的操作命令) [name]部分命名尽量表达出此次版本变化内容。
4. 禁止项
- 添加表字段只能用ALTER…ADD,严禁删表重建。
删表重建会删除生产环境的所有表数据,严格禁止!!
- 已提交的数据库版本文件严禁再修改提交。
一旦提交了数据库版本文件,则有可能被其他同事拉取启动或者部署开发、生产环境对数据库做相应变更,若再修改同一个版本文件提交会对他人或公共环境数据库造成破坏或经flyway检测不通过无法启动!
- 开发、测试、生产等公用环境原则上不允许直接修改flyway_schema_history表。
flyway_schema_history是数据库记录当前数据库版本信息的表。在不熟悉工具时进行操作会造成数据库结构及数据问题。
- 原则上禁止执行删表,删数据相关sql。
所有维护的数据库版本文件最终均会部署生产环境,删表与删数据必须慎重确定不会影响生产环境功能及不会丢失生产环境有用数据时才可进行。在不熟悉工具时进行操作会造成数据库数据丢失。
五、flyway配置和使用(springboot整合,进行配置连接和测试)
1、添加pom依赖
<!--导入flyway依赖-->
找到dependencies父标签,在里面添加如下依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway.version}</version>
</dependency>
2、yml(或properties)文件中配置flyway
以pg数据库为例:
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/你的数据库
username: 你的账户名称
password: 你的密码
# flyway数据库版本控制
flyway:
# 激活flyway
enabled: true
# 编码格式
encoding: UTF-8
# 禁止清楚数据库表
clean-disabled: true
# 指定 baseline 的版本号,缺省值为 1, 低于该版本号的 SQL 文件, migrate 的时候被忽略
baseline-version: 1
# sql文件目录
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表
# 如果指定 schema 包含了其他表,但没有 flyway schema history 表的话,设置为 true 后, flyway 将在需要 baseline 的时候, 自动执行一次 baseline
baseline-on-migrate: true
# 设置为true,当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表
baselineOnMigrate: true
3. 建立一个空表数据库
4. 添加resources文件
5.添加sql脚本(.sql版本文件)
6.在sql脚本中写sql语句
7.启动项目
启动项目以后,在不报错的情况下,我们这个时候就可以在数据库看见我们的flyway_schema_history 表
,它里面以后存储的就是我们每次迭代的版本记录;同时我们在这里创建了一个表student也会在数据库中看到;此时说明整合成功!恭喜你可以使用了
flyway_schema_history 表
student表
六、其他知识
- flyway执行migrate必须在空白的数据库上进行,否则报错。
- 对于已经有数据的数据库,必须先baseline,然后才能migrate。
- clean操作是删除数据库的所有内容,包括baseline之前的内容。
- 尽量不要修改已经执行过的SQL,即便是R开头的可反复执行的SQL,它们会不利于数据迁移。
- 当需要做数据迁移的时候,更换一个新的空白数据库,执行下migrate命令,所有的数据库更改都可以一步到位地迁移过去。
- 已经提交的版本建议不要再去数据库进行修改,当觉得这次提交有失误时候,重新进行一次版本迭代进行提交
七、关于flyway配置使用描述
flyway.baseline-description对执行迁移时基准版本的描述.
flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
flyway.check-location检查迁移脚本的位置是否存在,默认false.
flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false.
flyway.enabled是否开启flywary,默认true.
flyway.encoding设置迁移时的编码,默认UTF-8.
flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false.
flyway.init-sqls当初始化好连接时要执行的SQL.
flyway.locations迁移脚本的位置,默认db/migration.
flyway.out-of-order是否允许无序的迁移,默认false.
flyway.password目标数据库的密码.
flyway.placeholder-prefix设置每个placeholder的前缀,默认${.
flyway.placeholder-replacementplaceholders是否要被替换,默认true.
flyway.placeholder-suffix设置每个placeholder的后缀,默认}.
flyway.placeholders.[placeholder name]设置placeholder的value
flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema.
flyway.sql-migration-prefix迁移文件的前缀,默认为V.
flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__
flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql
flyway.tableflyway使用的元数据表名,默认为schema_version
flyway.target迁移时使用的目标版本,默认为latest version
flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
flyway.user迁移数据库的用户名
flyway.validate-on-migrate迁移时是否校验,默认为true
八、分环境配置多套数据库版本文件示例
为解决不同生产环境部分sql版本文件不通用的问题
1. 配置文件目录结构
环境配置文件yml/properties 要与db文件下的,名称一致
2. 主配置文件:application.properties、yml
使用spring.profiles.active=xxx
指定激活的环境
3. 生产环境1配置文件
只需要修改flyway
配置下的locations
,在原有的路径后添加文件路径即可;
当然还要写数据库连接信息
4. 生产环境2配置文件与环境1文件类似,对应将版本文件目录与数据源改成环境2的。
九、补充说明
-
首次使用flyway进行版本迭代时,不需要空表也可以进行增删改;还可以创建表;
-
其实配置完flyway的pom依赖和yaml配置,不用去写sql脚本就可以看看flyway是否配置成功了;
-
先配置pom和yml文件;
-
建立classpath也就是在resources包下新目录结构为db/migration (
db.migration
)的包如下: -
然后我们自己手动去target包下更新这个资源包 如下:
-
最后直接运行项目,看看你的数据库是不是多了一个flyway_schema_history这个表,就代表配置成功