flyway最佳生产实践

为什么使用flyway

一般的部署流程

  • 开发人员将应用程序打包、按顺序汇总并整理数据库升级脚本
  • DBA拿到数据库升级脚本检查、备份、执行,以完成数据库升级
  • 应部署人员拿到应用部署包,备份、替换,以完成应用程序升级


用上 Flyway 之后的应用部署流程大概是这样的:

  • 开发人员将应用程序打包(直接jenkins piplen 流程线构建 这时候flyway就已经在对应的环境执行了,脚本已经在库里生成了)
  • 应部署人员拿到应用部署包,备份、替换,以完成应用程序升(Flyway将自动执行升级/备份脚本)—> 我们这边是Jenkins ci集成化构建部署,dockerfile构建镜像 ,k8s容器编排,在ci的过程中脚本就已经执行了,就不需要部署人员再去操作数据库了。

在我平时的团队开发中,我们的代码是有版本控制的,可以多人协作持续集成(工具也非常多)。但是数据库的脚本确实需要手动的去执行,团队内人多,你执行你的我执行我的,就会导致很多问题:

  • 这台机器上的数据库处于什么状态?
  • 此脚本是否已应用?
  • 测试环境的数据库表结构和生产是否一致?
  • 测试环境要新增一台应用实例,该如何搭建数据库,必备的数据和表结构如何快速同步?

所以工作中,经常听到测试小伙伴们抱怨,明明已经提测了,但是却出现 A环境正常运行,B环境就报错,找开发定位又花费很多时间。究其原因,大多数是因为数据库没有类似代码那样的版本控制自动化工具,导致管理混乱。

Flyway 这个数据库迁移库就是要解决这个问题的,可以帮我们根据数据库当前的状态,区分哪些脚本执行过,哪些没有执行,然后根据目标数据库的当前状态,决定应该执行哪些数据库脚本


方案一

将flyway 单独维护在一个项目中,上线时手动操作,版本信息统一管理

项目地址

flyway

目录结构以及命名规范

项目结构

└─ibeautypass-ly-flyway
└─src
└─main
└─resources
└─db
└─migration
├─customer (命名规范:项目名称)
│ ├─version_1_0_0 (版本号 )
│ ├─V1_0_0_202204012042_02__create.sql (版本号 )
│ └─version_1_0_1
│ ├─V1_0_0_202204112042_02__update.sql (版本号 )
└─minapp (命名规范:项目名称)
├─version_1_0_0 (版本号 )
│ ├─V1_0_0_202204012042_01__create.sql (版本号 )
└─version_1_0_1
│ ├─V1_0_0_202204112042_01__update.sql (版本号 )

![image.png](https://img-blog.csdnimg.cn/img_convert/42953389a0c06e0b5465a80938c1b352.png#clientId=u85b77ec0-71ca-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=435&id=u90f1a424&margin=[object Object]&name=image.png&originHeight=544&originWidth=499&originalType=binary&ratio=1&rotation=0&showTitle=true&size=49535&status=done&style=none&taskId=ucd2cbd3f-d75f-4033-8be8-5145feb902e&title=项目结构以及命名规范&width=399.2 “项目结构以及命名规范”)

命名规范

在定义初始化脚本时,版本号建议为V+(编号)+yyyymmddhhmm+组号(一组01,二组02)+ __(为双下划线)+create,例如
V1_0_0_202204012042_01__create.sql。

在定义变更版本时,版本号为 V+(编号)+yyyymmddhhmm+组号(一组01,二组02)+ __(为双下划线)+update名称,例如
V1_0_0_202204112042_01__update.sql。
:::info
💡 注意,flyway严格按照版本号执行
:::
其中V1_0_0_202204012042_01__create.sql(初始化脚本)为项目所有的表结构与数据

-- SKU
CREATE TABLE [dbo].[SM_Sku] (
  [spu_id] varchar(15)  NULL,
  [sku_id] varchar(15) COLLATE Chinese_PRC_CI_AS  NULL,
  [delete_flag] int DEFAULT 0 NULL,
  [id] int  IDENTITY(1,1) NOT NULL,
  [createTime] datetime2(0)  NULL,
  [updateTime] datetime2(0)  NULL,
  [createBy] varchar(30)  NULL,
  [updateBy] varchar(30)  NULL,
  CONSTRAINT [PK__SM_Sku__3213E83F92763DA0] PRIMARY KEY CLUSTERED ([id])
  WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
  ON [PRIMARY]
)
ON [PRIMARY]
GO

其中V1_0_0_202204112042_01__update.sql 脚本如下

-- 历史套餐默认客户全部
update TB_Package_P set TB_Package_P.customer_scope = 0;
-- 历史套餐默认小程序不展示
update TB_Package_P set TB_Package_P.min_app_display = 1;
-- 初始化
update TB_Package_P set TB_Package_P.create_by = '000000000';
-- 初始化默认门店图片
UPDATE
TK_Entity  SET Img = 'https://staticaliyun.meibangtech.com//data/门店图片.jpg'
    WHERE Img IS NULL
运行方式

java -jar ibeautypass-ly-flyway-1.0-SNAPSHOT.jar

方案二

将flyway整合在项目中,随项目启动自动执行sql脚本,每个项目都各自维护sql脚本

依赖

<dependencies>
  <dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
  </dependency>
</dependencies>
<build>
  <plugins>
    <plugin>
      <groupId>org.flywaydb</groupId>
      <artifactId>flyway-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

配置

spring:
  flyway:
    enabled: true
    # sql文件存放目录
    locations: classpath:db/migration
    baseline-on-migrate: true
    baseline-version: 0
    encoding: utf-8
    # 执行顺序,生产需要改为true
    out-of-order: false
    # 禁止clean命令
    clean-disabled: true
    validate-on-migrate: true
    table: miniapp_schema_version
命名规范

SQL脚本文件名必须遵循以下命名规则:V[_][description] 。
版本号的数字间以下划线(
)分隔开,版本号与描述间以连续的两个下划线(
_ )分隔开。如V1_0_0_202204151646__update.sql.

项目结构

SQL脚本文件放在启动类对应的resource目录的db/migration
![image.png](https://img-blog.csdnimg.cn/img_convert/0afef46a5b7077c99c79d05e68194757.png#clientId=u92651886-e750-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=326&id=u2a5ffd53&margin=[object Object]&name=image.png&originHeight=326&originWidth=472&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18010&status=done&style=none&taskId=u224bb092-a7a0-481d-ae25-c8e0c52233e&title=&width=472)

对比:

优点缺点
方案一解耦,所有的项目统一在一个项目里面管理不同组上线时间节点不同,版本管理需要非常严格,学习成本较大
每次都需要单独切到这个工程执行对应分支
方案二使用方便,维护成本较低和项目高耦合
直接在jenkins构建的时候运行脚本不需要单独执行
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值