数据库版本管理框架-Flyway(从入门到精通)
一、flyway简介
Flyway是一个简单开源数据库版本控制器(约定大于配置),主要提供migrate、clean、info、validate、baseline、repair等命令。它支持SQL(PL/SQL、T-SQL)方式和Java方式,支持命令行客户端等,还提供一系列的插件支持(Maven、Gradle、SBT、ANT等)。
二、使用Flyway背景
部门开发一直是后端人员自行维护新增脚本,所以每次部署项目测试,都需要后端开发人员将 sql脚本在对应环境数据库上执行一遍,这样就造成有时候脚本文件混乱或者忘记执行,导致一些不必要的麻烦,所以就想要使用一款可以记录SQL文件版本迭代的工具。
三、Springboot集成Flyway
废话少说,我们直接开始进行Springboot的集成吧。
首先看一下Flyway执行流程:
1)Flyway 会扫描配置的脚本目录下的脚本文件;
2)如果历史记录表不存在,则新建历史记录表;
3)如果是一次性执行脚本(V),按版本号从小到大执行迁移脚本,与当前历史表中的版本号做对比,大于当前版本号的脚本才会被执行迁移;
4)如果是可重复执行脚本(R),检查脚本是否有变动,有变动的可重复脚本才会被执行迁移;
1.引入依赖
Springboot2.x版本已经对Flyway有所依赖了,我们直接引入,不需要进行版本的申明,有时你写上版本号还可能被项目自动覆盖哦,这块注意检查一下。
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId>
</dependency>
2.配置文件 yml
要迁移的数据库的 DB url。 如果未设置,则使用主要配置的数据源,正常我们的项目都有jdbc的连接信息,我们使用默认就行,无需配置。
pring:flyway:# 开启 flywayenabled: true# 检测迁移脚本的路径是否存在,如不存在,则抛出异常check-location: true# 是否禁用数据库清理clean-disabled: true# SQL 迁移的编码encoding: UTF-8# 迁移脚本的位置,默认db/migration.locations: classpath:flyway# 版本记录信息表table: tb_flyway_history# SQL 迁移的文件名前缀。sql-migration-prefix: V# SQL 迁移的文件名分隔符。sql-migration-separator: __# SQL 迁移的文件名后缀。sql-migration-suffixes: .sql# 是否在执行迁移时自动调用验证。validate-on-migrate: true# 迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.baseline-on-migrate: true#如果不想用元数据的表明,可以更改元表名spring.flyway.table=test
3.新建flyway文件夹和sql文件
Flyway 的默认扫描迁移脚本目录在:spring.flyway.locations: classpath:db/migration,用于扫描的迁移脚本目录
Flyway 的默认版本变化记录表名称:spring.flyway.table: flyway_schema_history,用于记录所有的版本变化记录(可在配置文件中进行更改)
3.1 根据第2步配置了迁移脚本目录,我们在 src/main resources 目录下创建flyway目录,如下图:

3.2 下面我们创建两个sql脚本,如上图:
SQL脚本的命名规则(约定大于配置必须遵守)
命名规则主要有两种:
1、仅需要被执行一次的SQL命名以大写的"V"开头,V+版本号(版本号的数字间以”.“或”_“分隔开)+双下划线(用来分隔版本号和描述)+文件描述+后缀名。例如: V20231100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql 。
2、可重复运行的SQL,则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。(不推荐使用)比如: R__truncate_user_dml.sql 。
前缀:V用于版本化(可配置), U用于撤消(可配置)和 R用于可重复迁移(可配置)
版本:带点或下划线的版本可以根据需要分开多个部分(不适用于可重复的迁移)
分隔符 :( __两个下划线)(可配置)
描述:下划线或空格分隔单词
后缀:.sql(配置)
-- V1.0.0__user_create.sql 创建标签表
DROP TABLE IF EXISTS tb_user;
CREATE TABLE `tb_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',`user_code` varchar(100) DEFAULT NULL COMMENT '用户code',`user_name` varchar(50) DEFAULT NULL COMMENT '用户名称',`user_type` int(2) DEFAULT 3 COMMENT '用户类型',`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';-- V1.0.1__user_insert.sql 标签表插入数据
INSERT INTO tb_user
(user_code, user_name, user_type)
values("U12345", "张三", 1);
四、启动项目
2022-05-17 16:13:37.912||||[main] INFO o.f.core.internal.database.base.DatabaseType 49 - Database: jdbc:mysql://localhost:3366/db (MySQL 5.7)
2022-05-17 16:13:37.999||||[main] INFO org.flywaydb.core.internal.command.DbValidate 49 - Successfully validated 2 migrations (execution time 00:00.048s)
2022-05-17 16:13:38.025||||[main] INFO org.flywaydb.core.internal.command.DbMigrate 49 - Current version of schema `db`: << Empty Schema >>
2022-05-17 16:13:38.039||||[main] INFO org.flywaydb.core.internal.command.DbMigrate 49 - Migrating schema `db` to version "1.0.0 - create"
2022-05-17 16:13:38.123||||[main] INFO org.flywaydb.core.internal.command.DbMigrate 49 - Migrating schema `db` to version "1.0.1 - insert"
2022-05-17 16:13:38.157||||[main] INFO org.flywaydb.core.internal.command.DbMigrate 49 - Successfully applied 2 migrations to schema `db` (execution time 00:00.153s)
数据库中flyway记录历史信息表如下:

五、 开发时注意事项
1.报错后需要删除flyway_schema_history中记录,否则启动失败
2.V的优先级高于R,假如三个V迁移脚本和一个R(无论新建还是修改)一起执行,其中一个V报错,则V会
全部执行完成且记录到flyway_schema_history中,而R不执行且不记录,删除表中报错记录后,查询启
动,则执行原错误V和未执行的R
3.多个要执行的R中,如果出现了其中一个出现了错误,则在其后的R都不执行
4.R的执行顺序根据命名来进行排序
5.一个文件中ddl并不由一个事务管理,比如创建三个表,中间创建表语句报错,则第一个表还是会创建
成功并且提交事务
6.已经执行过的迁移文件(V)不能修改,否则报错。
7.同一个迁移文件下同表内DDL无法回滚,DML可回滚, 从报错点开始不往下执行,Flyway使用数据库锁
机制
8.版本号相同会报错(Found more than one migration with version 1.0.0.9)
9.同一个迁移文件下假设都是dml,那么如果中间出现错误,所有的dml语句都会回滚
10.删除sql文件后启动会报错,报错如下
If you removed this migration intentionally, run repair to mark the migration as
deleted.
六、部署上线时注意事项
如果不手动创建元数据表,则需要进行以下配置,用于自动创建
validate-on-migrate: true
如果数据库不是空表,则需进行以下配置,否则启动报错
baseline-on-migrate: true
clean命令会删除数据库中所有表,包括数据,结构等,这是不合理的,所以需要进行以下配置
clean-disabled: true (该配置由于默认值不合理,所以在V9版本中修改默认值由false为true)
使用flyway要注意版本兼容问题,springboot与flyway,flyway与数据库版本,否则启动报错
如果启动的时候像忽略某些迁移文件,可进行以下参数配置
baseline-version=20230809,以忽略 20230809 版本以及之前的所有 migration
多人开发中,如果一个人提交V2一个人提交V1,而V2先入库执行了,那么V1入库就不会执行,如果需要执行则需进行如下配置,但是不建议这么做
out-of-order=true
相关文章:
数据库版本管理框架-Flyway(从入门到精通)
一、flyway简介 Flyway是一个简单开源数据库版本控制器(约定大于配置),主要提供migrate、clean、info、validate、baseline、repair等命令。它支持SQL(PL/SQL、T-SQL)方式和Java方式,支持命令行客户端等&am…...
外网访问内网服务器使用教程
如何在任何地方都能访问自己家里的笔记本上的应用?如何让局域网的服务器可以被任何地方访问到?有很多类似的需求,我们可以统一用一个解决方案:内网穿透。内网穿透的工具及方式有很多,如Ngrok、Ssh、autossh、Natapp、F…...
C# Dictionary 利用 ContainsValue 查询指定值是否已经存在
.NET Framework : 4.7.2IDE : Visual Studio Community 2022OS : Windows 10 x64typesetting : Markdownblog : niaoge.blog.csdn.net 简介 本文介绍如何查询Dictionary 中某个值是否已经存在。 ContainsValue 命名空间: System.Collections.Generic 程序集: System.Collect…...
招不到人?用C语言采集系统批量采集简历
虽说现在大环境不太好,很多人面临着失业再就业风险,包括企业则面临着招人人,找对口专业难得问题。想要找到适合自己公司的人员,还要得通过爬虫获取筛选简历才能从茫茫人海中找到公司得力干将。废话不多说,直接开整。 1…...
HXDSP2441-Demo板
板卡图示 下图为HXDSP2441DEMO板,HXDSP2441DEMO板是围绕HXDSP2441构建的芯片演示验证平台。 板卡简介 除了为HXDSP2441芯片提供供电、时钟、储存、网络及调试电路,来实现芯片最基本的功能,也添加了相关模块以搭建HXDSP2441的典型应用场景…...
静态路由的原理和配置
一.路由器的工作原理 首先我们知道路由器是工作在网络层的,那就是三层设备。网络层的功能主要为:不同网段之间通信、最佳路径选择也就是逻辑地址(ip地址)寻址、转发数据。 1.路由器是什么 路由器是能将数据包转发到正确的目的地…...
Ubuntu20.04降低linux版本到5.4.0-26-generic
前言 试用ubuntu20.04安装昇腾的驱动和cann的时,出现如下问题: (base) rootubuntu:/home/work# ./Ascend-hdk-910-npu-driver_23.0.rc3_linux-aarch64.run --full Verifying archive integrity... 100% SHA256 checksums are OK. All good. Uncompr…...
C++ 类型萃取
什么是 type_traits 在C中,类型萃取(type_traits)是一种编译时技术,用于在编译期间获取和操作类型的信息。 主要用于泛型编程以及在编译时做出决策。 类型萃取可以帮我们检查和处理类型特性,从而优化代码、避免错误或…...
【JVM从入门到实战】(四)类的生命周期
什么是类的生命周期 类的生命周期描述了一个类加载、连接、初始化、使用、卸载的整个过程 一个类完整的生命周期如下: 加载阶段 加载阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方式获取字节码信息。 程序员可以使用Java代码拓展的不同的渠道…...
2023年度美食关键词-葱油花卷
2023年即将过去了,总结这一年的美食关键词,对于我来就,应该就是-大葱了。 前一周,朋友送了我5大葱,在北方,大葱是家家户户必不可少的食材,尤其对于面食爱好者来说,大葱的加入无疑让…...
「Verilog学习笔记」简易秒表
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 timescale 1ns/1nsmodule count_module(input clk,input rst_n,output reg [5:0]second,output reg [5:0]minute);always (posedge clk or negedge rst_n) begin if (~rst…...
《每天一个Linux命令》 -- (12) file命令
欢迎阅读《每天一个Linux命令》系列 !在本篇文章中,将说明file命令用法。 概念 file命令是Linux系统下的文件类型识别命令,用于识别文件的类型。 命令操作 file命令的语法如下: file [选项] 文件命令详细解释 以下是 file 命…...
如何使用ArcGIS Pro制作类似CAD的尺寸注记
经常使用CAD制图的朋友应该比较熟悉CAD内的尺寸标注,这样的标注看起来直观且简洁,那么在ArcGIS Pro内能不能制作这样尺寸注记呢,答案是肯定的,这里为大家介绍一下制作的方法,希望能对你有所帮助。 数据来源 本教程所…...
Go语言bufio包的使用
准备文本文件 rpc_intro.txt RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议, 允许调用不同进程空间的程序。RPC 的客户端和服务器可以在一台机器上,也可以在不同的机器上。程序员使用时,就像调用本地程序一样&…...
计算机网络之IP篇
来源自小林Coding博客,阅读后部分精简笔记 目录 一、IP 的基本认识 二、DNS 三、ARP 四、DHCP 五、NAT 六、ICMP 七、IGMP 七、ping 的工作原理 ping-----查询报文的使用 traceroute —— 差错报文类型的使用 八、断网了还能 ping 通 127.0.0.1 吗&…...
Java中JDK类库常用的6种设计模式
Java中JDK类库常用的6种设计模式:1、抽象工厂。2、建造者模式。3、工厂模式。4、原型模式。5、单例模式。6、适配器模式。 1、抽象工厂 javax.xml.parsers.DocumentBuilderFactory抽象类。 public static DocumentBuilderFactory newInstance()方法。 类功能&…...
C++ 用法全面剖析
我们知道,参数的传递本质上是一次赋值的过程,赋值就是对内存进行拷贝。所谓内存拷贝,是指将一块内存上的数据复制到另一块内存上。 对于像 char、bool、int、float 等基本类型的数据,它们占用的内存往往只有几个字节,对…...
数据库结构
三级结构 内模式:也称为物理模式,它是数据库中数据的物理存储表示,描述了数据在存储介质上的存储方式和物理结构,通常由数据库管理员进行定义。 概念模式:也称为逻辑模式,它是对数据库中全体数据的逻辑表示…...
什么是HTML以及超链接,特殊符号转义的简单使用
目录 什么是HTML🌸 HTML版本 版本说明🌸 XHTML和HTML的区别 超链接🌸基本语法🌸链接的分类 特殊符号 什么是HTML HTML 不是编程语言,没有逻辑处理能力,没有计算能力,不能动态地生成内容&#x…...
汽车销售技巧培训应该学习哪些内容
汽车销售技巧培训应该学习哪些内容 随着汽车市场的竞争日益激烈,汽车销售技巧培训对于提高销售人员的销售能力和服务水平至关重要。本文将介绍汽车销售技巧培训应该学习哪些内容,并结合案例进行分析。 一、产品知识 作为销售人员,了解所销售…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
