数据库版本管理工具Flyway入门实战

news2024/12/27 12:15:31

From version control to continuous delivery, Flyway helps individuals, teams, and enterprises build on application delivery processes to automate database development. 

1.引言

在项目开发中,一直在探索如何进行数据库的版本管理。关注的公众号推送了数据库版本管理工具Flyway,Flyway支持的数据库为  Oracle,  SQL Server (including Amazon RDS and Azure SQL Database),  Azure Synapse (Formerly Data Warehouse),  DB2,  MySQL  (including Amazon RDS, Azure Database & Google Cloud SQL),  Aurora MySQL,  MariaDB,  Percona XtraDB Cluster,  TestContainers,  PostgreSQL  (including Amazon RDS, Azure Database, Google Cloud SQL, TimescaleDB, YugabyteDB & Heroku),  Aurora PostgreSQL,  Redshift,  CockroachDB,  SAP HANA,  Sybase ASE,  Informix,  H2,  HSQLDB,  Derby,  Snowflake,  SQLite  and  Firebird.

最近实际操作了一下,结合官方文档,记录一下如何应用于Spring Boot项目中。

2.工作机制

Flyway默认需要在数据库中新建一个metadata数据表,默认表名为flyway_schema_history,在该表中保存着每次 migration (迁移)的记录, 记录包含 migration 脚本的版本号和 SQL 脚本的 checksum 值。下图表示了多个数据库版本。

preview

对应记录表:

表中记录5个版本,对应配置文件下(第三节 的locations值),五个文件,如图所示。

 Flyway 扫描文件系统或应用程序的类路径读取 DDL 和 DML 以进行迁移。根据metadata 表进行检查迁移。如果脚本声明的版本号小于或等于标记为当前版本的版本号之一,将忽略它们。其余迁移是待处理迁移:可用,但未应用。最后按版本号对它们进行排序并按顺序执行 并将执行结果写入 metadata 表。 

3.SQL文件命名规则

Flyway 将 SQL 文件分为 Versioned 、Repeatable 和 Undo 三种:

  • Versioned 用于版本升级, 每个版本有唯一的版本号并只能执行一次.
  • Repeatable 可重复执行, 当 Flyway检测到 Repeatable 类型的 SQL 脚本的 checksum 有变动, Flyway 就会重新应用该脚本. 它并不用于版本更新, 这类的 migration 总是在 Versioned 执行之后才被执行。
  • Undo 用于撤销具有相同版本的版本化迁移带来的影响。但是该回滚过于粗暴,过于机械化,一般不推荐使用。一般建议使用 Versioned 模式来解决。

这三种的命名规则如下图:

naming.png

  • Prefix 可配置,前缀标识,默认值 V 表示 VersionedR 表示 RepeatableU 表示 Undo
  • Version 标识版本号, 由一个或多个数字构成, 数字之间的分隔符可用点 . 或下划线 _
  • Separator 可配置, 用于分隔版本标识与描述信息, 默认为两个下划线 __
  • Description 描述信息, 文字之间可以用下划线 _ 或空格 分隔
  • Suffix 可配置, 后续标识, 默认为 .sql

4.项目引入

<!--    数据库版本管理工具 定义properties    -->
<flyway.version>8.5.13</flyway.version>


<dependency>
     <groupId>org.flywaydb</groupId>
     <artifactId>flyway-core</artifactId>
     <version>${flyway.version}</version>
</dependency>
<dependency>
      <groupId>org.flywaydb</groupId>
      <artifactId>flyway-mysql</artifactId>
      <version>${flyway.version}</version>
</dependency>

注意:因为我使用的数据库为MySql版本现在Flyway不直接支持,需要添加对于mysql的支持引入。

5. 配置文件

application.yml配置属性

spring:
  datasource:
    #???????
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ${DATABASE_SYSTEM_URL}
    username: ${DATABASE_SYSTEM_USERNAME}
    password: ${DATABASE_SYSTEM_PASSWORD}
  #数据库版本管理工具flyway配置
  flyway:
    schemas: leading_info_collection  # 数据库名称
    enabled: true #是否开启flyway
    encoding: utf-8 #编码方式
    clean-on-validation-error: false #当发现校验错误时是否自动调用clean,默认false.
    baseline-on-migrate: true # 如果数据库不是空表,需要设置成 true,否则启动报错
    baseline-version: 0 # 与 baseline-on-migrate: true 搭配使用
    clean-disabled: true  # 禁止清理数据库表
    locations: classpath:db/migration #设定 SQL 脚本的目录,多个路径使用逗号分隔, 比如取值为                 
    #classpath:db/migration,filesystem:/sql-migrations
    out-of-order: true #是否按照版本顺序执行sql文件
    validate-on-migrate: false #启动时是否校验最新的版本迁移文件

此处列出了比较重要的一些配置,具体配置可以查看官方文档。这里讲解一下重要的配置。

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

6.实践

6.1 初次启动项目

如下图所示,数据库中没有任何表,现在有V0版本,V0版本为初始化数据表

DROP TABLE IF EXISTS `problem_info`;
CREATE TABLE `problem_info` (
       `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
       `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
       `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
       `subject` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '描述主题',
       `subjection_model` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '所属模块',
       `detail` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '具体描述',
       `ImageNames` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '图片地址',
       `verificationCode` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '修改删除使用的验证码',
       PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=144 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='问题信息表';

 启动项目,控制台打印日志如下:

此时数据库新建了 flyway_schema_history表,并新建了一条数据,执行了initdb.sql文件,新建了problem_info表格。

6.2 新增版本

现在按照命名规则,新增 V1版本添加一个学生的数据表,重新启动项目。

CREATE TABLE student (
     id INT(4),
     name VARCHAR(20),
     sex CHAR(1));

 

6.3 更改版本文件报错

现在更改V1__add_student_table.sql文件。

CREATE TABLE student (
     id INT(4),
     name VARCHAR(20),
     sex CHAR(1));

DROP PROCEDURE IF EXISTS `sp_select_one_age_dogs`;

delimiter $
CREATE PROCEDURE sp_select_one_age_dogs()
begin
select * from dog d where d.dog_age <=1;
end $

再重新启动项目,报错信息如下。 

6.4 重复执行SQL文件

新建一个以R开头的可重复执行的SQL文件R__add_procedure.sql,重新启动项目。

 

7.Maven插件

再pom.xml文件中添加对应的Maven插件,配置好数据库连接。

 <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>${flyway.version}</version>
                <configuration>
                    <url>${env.DATABASE_SYSTEM_URL}</url>
                    <user>${env.DATABASE_SYSTEM_USERNAME}</user>
                    <password>${env.DATABASE_SYSTEM_PASSWORD}</password>
                    <driver>com.mysql.cj.jdbc.Driver</driver>
                </configuration>
            </plugin>

更新maven插件列表,就可以看到flyway的全部命令了。

此时,我们双击执行上图中的flyway:migrate的效果和启动整个工程执行migrate的效果是一样的。

其它命令的作用如下列出,各位可自行实验体会:

  • 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值,如果值相同则验证通过,否则失败。

8.最佳实践

通过上面的介绍相信你很快就会使用 Flyway 进行数据库版本控制了。这里总结了一些在实际开发中的使用经验:

  1. 生产务必禁 spring.flyway.cleanDisabled=false 。
  2. 尽量避免使用 Undo 模式。
  3. 开发版本号尽量根据团队来进行多层次的命名避免混乱。比如 V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql ,这种命名同时也可以获取更多脚本的开发者和相关功能的信息。
  4. spring.flyway.outOfOrder 取值 生产上使用 false,开发中使用 true
  5. 多个系统公用一个 数据库 schema 时配置spring.flyway.table 为不同的系统设置不同的 metadata 表名而不使用缺省值 flyway_schema_history 。

9.目前遇到的问题

  1. 新建新版本的sql版本文件,项目启动后不能再更新,这会导致在一次开发中需要使用多个版本文件。目前解决的办法可以删除对应metadata数据库对应的最新版本数据(奇技淫巧)。
  2. sql文件的语句必须是可重复执行的,比如插入数据,数据插入后,如果遇到情况1,重新执行对应数据库文件,如果sql文件不能重新执行,项目启动时会出现sql语法错误,项目启动失败。

10.总结

在进行了如上的实验后,相信我们都已经掌握了flyway的初步使用。目前还是在探索阶段,实际开发中还没有使用起来,后续肯定还会遇到很多问题,本博客会依据实际情况,持续不断更新。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/787881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

踩坑 视觉SLAM 十四讲第二版 ch8 编译及运行问题

1.fmt相关 CMakeLists.txt中&#xff1a;在后面加上 fmt target_link_libraries(optical_flow ${OpenCV_LIBS} fmt ) target_link_libraries(direct_method ${OpenCV_LIBS} ${Pangolin_LIBRARIES} fmt )2.不存在用户定义的从 "std::_Bind<void (OpticalFlowTracker::…

动态内存管理函数的使用与优化技巧(内存函数、柔性数组)

目录 前言 一、动态内存函数 为什么存在动态内存分配 动态内存函数介绍 malloc和free calloc realloc 常见的错误 经典笔试题目 二、C/C程序的内存开辟 三、柔性数组 柔性数组的特点&#xff1a; 柔性数组的使用 柔性数组的优势 前言 动态内存管理函数是C语言中非常重要的一部…

Verilog 学习之路(三)——牛客刷题篇

1.输入序列连续的序列检测 题面 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJH9kHFH-1690301233803)(https://s2.loli.net/2023/07/26/HJPXR2mhbaVCG6d.png)]思路 对于序列检测题目&#xff0c;常规的解法有两种&#xff1a;状态机法和序列缓存…

需求管理全过程流程图及各阶段核心关注点详解

分析报告指出&#xff0c;多达76%的项目失败是因为差劲的需求管理&#xff0c;这个是项目失败的最主要原因&#xff0c;比落后的技术、进度失控或者混乱的变更管理还要关键。很多项目往往在开始的时候已经决定了失败&#xff0c;谜底就在谜面上&#xff0c;开始就注定的失败&am…

python-基本数据类型

hello&#xff0c;这里是Token_w的文章&#xff0c;主要讲解python的基础学习&#xff0c;希望对大家有所帮助 整理不易&#xff0c;感觉还不错的可以点赞收藏评论支持&#xff0c;感谢&#xff01; 有没有一个人&#xff0c;你想给TA传个小纸条&#xff1f;用恺撒密码一展身手…

【Docker】Docker Compose的配置与部署

文章目录 一、Docker Compose1. Docker Compose 的概述2. Docker Compose 三大的概念3. Docker Compose 环境安装 二、YAML 文件格式及编写注意事项1. YAML 文件格式2. YAML 格式的注意事项3. YAML 数据结构3.1 基本类型3.2 实例3.3 YAML 特殊类型文本块锚点与引用 三、Docker …

【【直流电机驱动PWN】】

直流电机驱动PWN 前面都是沙县小吃&#xff0c;这里才是满汉全席 直流电机是一种电能转化成机械能的装置 直流电机有两个电极 当电机正接 电机正转 当电机负接 电机倒转 电机还有步进电机 舵机 无刷电机 空心杯电机 因为电机是一个大功率器件并不太好直接接在IO端口上所以我…

2023 年牛客多校第一场题解(上)

A Almost Correct 题意&#xff1a;给定长度为 n n n 的 01 01 01 串 s s s&#xff0c;构造一个排序网络&#xff0c;使得能够将除 s s s 之外的任意 01 01 01 序列正确排序&#xff0c;且 s s s 无法被正确排序。 T T T 组测试&#xff0c; 1 ≤ T ≤ 1 0 4 1 \le T \…

ASEMI代理海矽美快恢复二极管SFP6002的特性和应用分析

编辑-Z 二极管SFP6002是一种常见的电子元件&#xff0c;也被称为快恢复二极管。它具有快速恢复时间和低反向恢复电流的特点&#xff0c;适用于高频电路和开关电源等应用。 SFP6002的主要特性包括&#xff1a; 1. 快速恢复时间&#xff1a;SFP6002具有快速的恢复时间&#xff…

Git Gui相关术语

文章目录 Git Gui主界面相关术语- Amend Last Commit&#xff08;修正最后一次提交&#xff09;- Rescan&#xff08;重新扫描&#xff09;- Sign Off&#xff08;签名&#xff09;- Stage Changed Git Gui Commit菜单相关术语- Stage to Commit&#xff08;暂存到提交&#xf…

Ceph组件

Ceph组件 无论是想向云平台提供Ceph 对象存和 Ceph 块设备服务、部署Ceph 文件系统,或者是将 Ceph 用于其他目的,所有 Ceph 存储集群部署都从设置每个 Ceph 节点、网络开始。 一个Ceph 存储集群至少需要一个Ceph Monitor、Ceph Manager和 Ceph OSD (OBJECT STORAGE DAEMON对象存…

【MySQL】十三,索引的代价、MySQL数据结构选择的合理性

索引的代价 空间上的代价 每建立一个索引都要为它建立一棵B树&#xff0c;每一棵B树的每一个节点都是一个数据页&#xff0c;一个页默认会占用 16KB 的存储空间&#xff0c;一棵很大的B树由许多数据页组成&#xff0c;那就是很大的一片存储空间。 时间上的代价 每次对表中的…

前端开发中的常见优化

目录 外观 兼容 不同尺寸&#xff08;包裹&#xff0c;height:100%&#xff09; 不同 浏览器 隐藏滚动条 的 不同属性名 重排->重绘 不显示 display:none->禁用disable 性能 导航重复&#xff08;修改原型push、replace方法&#xff09; 搜索防抖 import { debo…

【Docker】Docker私有仓库管理

目录 一 、Harbor 简介1.1 什么是Harbor1.2Harbor的特性1.3Harbor的构成 二、Harbor部署2.1 部署 Docker-Compose 服务2.2 部署 Harbor 服务2.3启动Harbor2.4 创建一个新项目2.5 在其他客户端上传镜像 三、配置Harbor 高可用四、维护管理Harbor4.1. 通过 Harbor Web 创建项目4.…

提升Web3安全性和用户体验:元事务和加密技术的应用

在Web3中&#xff0c;去中心化应用程序&#xff08;DApps&#xff09;是一种基于区块链技术的应用程序&#xff0c;它们通过智能合约实现透明、安全、去中心化的业务逻辑。然而&#xff0c;DApps的使用门槛比传统的中心化应用程序更高&#xff0c;需要用户具备一定的技术知识&a…

python简单入门

python简单入门 文章目录 python简单入门[toc] 地址链接1. 官网2. 下载地址3. 官方文档 1. 第一章1.1 python解释器1.2 基础语法1.2.1 常见数据类型1.2.2 强制类型转换1.2.3 注释1.2.4 运算符1.2.5 字符串1.2.5.1 字符串的定义1.2.5.2 字符串拼接1.2.5.3 格式化字符串1.2.5.3 精…

profinet 调试记录

一、 树莓派运行codesys runtime Codesys control for Raspberry Pi (外网) 链接&#xff1a;https://pan.baidu.com/s/1vgURlEG_y4C5rj7rALdOdQ?pwdfkhr 提取码&#xff1a;fkhr 1. 用户名称要以 root 登录 若是普通用户&#xff0c;会提示&#xff1a;脚本必须以 root 身…

Facebook Messenger市场营销,跨境电商不可忽略的营销手段

营销始于广告。广告仍然是不可或缺的&#xff0c;但广告的方式正在发生变化。以前商家会使用广告邮件或者直接转到网站上的产品页面&#xff0c;但是这两种方法都存在很大问题。虽然企业可以通过电子邮件与潜在客户保持联系&#xff0c;但不能保证这些潜在客户会真正看广告邮件…

【算法与数据结构】104、111、LeetCode二叉树的最大/最小深度

文章目录 一、题目二、层序遍历法三、递归法四、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、层序遍历法 思路分析&#xff1a;两道题都可以用层序遍历&#xff08;迭代法&#xff09;来做&#xff0c;遍历完…

通付盾获苏州市工业互联网产业联盟“工业互联网看苏州”先锋企业

近日&#xff0c;苏州市工业互联网产业联盟公布2022年度苏州市工业互联网产业联盟系列评选获评名单&#xff0c;通付盾荣获“工业互联网看苏州”先锋企业。 为加快推动工业互联网在数字赋能产业创新集群融合发展中发挥更显著作用&#xff0c;进一步完善苏州市工业互联网产业生态…