1、项目启动,应用程序完成数据库连接池的建立后,Flyway自动运行。
2、初次使用时,flyway会创建一个 flyway_schema_history 表,用于记录sql执行记录。
3、Flyway会扫描项目指定路径下(默认是 classpath:db/migration )的所有sql脚本,与 flyway_schema_history 表脚本记录进行比对。如果数据库记录执行过的脚本记录,与项目中的sql脚本不一致,Flyway会报错并停止项目执行。
4、如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。
org.flywaydb flyway-core 5.2.4
spring: flyway: # 是否启用flyway enabled: true # 编码格式,默认UTF-8 encoding: UTF-8 # 迁移sql脚本文件存放路径,默认db/migration 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表 baseline-on-migrate: true
在resource目录下建立文件夹 db/migration,脚本文件命名以大写的"V"开头,V+版本号(版本号的数字间以”.“或”_“分隔开)+双下划线(用来分隔版本号和描述)+文件描述+后缀名。例如: V20201100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql
具体规范如下
【flyway使用规约】
版本号 ,使用社区最后的版本,不要使用商用版本( 商用版本支持回退)
flyway 脚本分分为初始脚本 (建表), DDL增量更新脚本, DML 增量更新脚本,文件名称及内容参考本规范定义的要求编写
配置了flyway 脚本自动升级的应用,必须遵循单应用单数据的规范, 禁止多个应用使用同一个数据库,并且各自启用各自的flyway,这种场景会有冲突
如果违反规范,建议flyway 只放一个微服务,并且每个版本有数据变更,都要和这个微服务的版本一起发
flyway 脚本在应用已经启动执行后,禁止已执行版本做增量修改,新修改需新建版本文件,否则启动版本冲突造成成构建失败。
建议方式一个迭代单个数据库所有数据脚本合并到当前版本ddl, dml 两个文件一次性执行。
对于边写边边调整数据结构,或追加数据变更方式不提倡,可参考RFQ 指引处理。
【flyway 脚本目录结构】
在java项目的 resources 目录下新增 db.migration 目录。存放升级脚本
【flyway 初始版本】
初始脚本放新java 项目的建库初始SQL脚本,
文件名规范:
类型 | 格式规范 | 案例 | 备注 |
---|---|---|---|
建表/索引初始脚本 | VYYYYMMDD__init-table.sql | V20170718__init-table.sql | 日期后为双下划线 |
数据初始化脚本 | VYYYYMMDD__init-data.sql | V20170719__init-data.sql | 日期同一天不能重复,作为flyway数据库表的时间字段,如有同一天的两类脚本,要么合并内容,要么拆成两天 |
内容规范:
1. 建表语句开始位置关闭外键校验, 结束位置开启外键校验
SET FOREIGN_KEY_CHECKS=0; -- 建表语句正文 SET FOREIGN_KEY_CHECKS=1;
2. 建表语句规范要求
参考数据标准建表规范要求:
mysql 建表语句规范:
1. 检表语句, 表名称 前后 加 ` 避免与保留字冲突
2. 字段名称 前后 加 ` 避免与保留字冲突
3. 字段名称建议大写
4. 指定字段非空及默认值
5. 指定字段描述 COMMENT
6. 含有索引,索引名称及字段名前后一律加 `
7. 指定数据存储引擎,默认字符集。
SET FOREIGN_KEY_CHECKS=0; CREATE TABLE `redis_server` ( `REDIS_ID` bigint(15) NOT NULL AUTO_INCREMENT COMMENT 'Redis_id', `REDIS_GROUP_ID` bigint(15) NOT NULL COMMENT 'Redis组ID', `REGION` varchar(16) DEFAULT NULL COMMENT 'Region', `IP` varchar(16) NOT NULL COMMENT 'IP', `REDIS_PORT` int(11) NOT NULL COMMENT 'Redis端口', `SENTINEL_PORT` int(11) DEFAULT NULL COMMENT '哨兵端口', `NODE_TYPE` varchar(16) DEFAULT NULL COMMENT '节点类型', `REMARK` varchar(500) DEFAULT NULL COMMENT '备注', `ENABLE_FLAG` char(1) DEFAULT 'Y' COMMENT '有效位标志', `CREATED_BY` varchar(50) DEFAULT NULL COMMENT '创建人', `CREATE_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期', `LAST_UPDATED_BY` varchar(50) DEFAULT NULL COMMENT '最后更新人', `LAST_UPDATE_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新日期', `ORG_ID` varchar(50) DEFAULT NULL COMMENT '组织ID', PRIMARY KEY (`REDIS_ID`), UNIQUE KEY `IDX_redis_server_u01_key` (`IP`,`REDIS_PORT`), KEY `IDX_redis_server_f01_group` (`REDIS_GROUP_ID`), KEY `IDX_redis_server_i01_nodetype` (`NODE_TYPE`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; SET FOREIGN_KEY_CHECKS=1; |
【flyway DDL 数据库表结构增量变更脚本规范(含索引)】
增量数据结构变更脚本按照如下规范命名文件:
文件名规范:
类型 | 格式规范 | 案例 | 备注 |
---|---|---|---|
增量数据机构DDL变更脚本 | VYYYYMMDD__ddl-项目迭代版本.sql | V20170930__ddl-v3.21.12.sql | 日期后为双下划线 |
增量数据结构DDL变更脚本 | VYYYYMMDD__ddl-项目补丁版本.sql | V20170930__ddl-v3.20.33.p01.sql | 日期后为双下划线 |
内容规范:
1. 增量数据结构更新DDL语句开始位置关闭外键校验, 结束位置开启外键校验
SET FOREIGN_KEY_CHECKS=0; -- 建表语句正文 SET FOREIGN_KEY_CHECKS=1;
2. 表新增的字段必须要指定是否非空,新增非空字段一定要设置默认值
案例
SET FOREIGN_KEY_CHECKS=0; -- ngx_server ALTER TABLE ngx_server ADD COLUMN HTTPS_PORT INT NULL COMMENT 'HTTPS端口' ; ALTER TABLE ngx_server ADD COLUMN SERVER_ROOM VARCHAR(32) COMMENT '机房'; ALTER TABLE ngx_server ADD COLUMN NGTOOL_PORT INT COMMENT 'ngtool端口'; ALTER TABLE ngx_server ADD COLUMN NGINX_VERSION VARCHAR(100) COMMENT 'Nginx版本号'; ALTER TABLE ngx_server ADD COLUMN OS VARCHAR(100) COMMENT 'OS内核版本'; ALTER TABLE ngx_server ADD COLUMN CPU INT COMMENT 'CPU核数'; ALTER TABLE ngx_server ADD COLUMN RAM INT COMMENT '内存'; ALTER TABLE ngx_server ADD COLUMN STORAGE INT COMMENT '存储'; ALTER TABLE ngx_server ADD COLUMN IS_REG_MONITOR_OK CHAR(1) COMMENT '是否注册监控成功'; -- redis_server ALTER TABLE redis_server ADD COLUMN SERVER_NAME VARCHAR(100) COMMENT '服务器名称'; ALTER TABLE redis_server ADD COLUMN REDIS_VERSION VARCHAR(100) COMMENT 'redis版本'; ALTER TABLE redis_server ADD COLUMN SERVER_ROOM VARCHAR(32) COMMENT '机房'; ALTER TABLE redis_server ADD COLUMN OS VARCHAR(100) COMMENT 'OS内核版本'; ALTER TABLE redis_server ADD COLUMN CPU INT COMMENT 'CPU核数'; ALTER TABLE redis_server ADD COLUMN RAM INT COMMENT '内存'; ALTER TABLE redis_server ADD COLUMN STORAGE INT COMMENT '存储'; ALTER TABLE redis_server ADD COLUMN IS_REG_MONITOR_OK CHAR(1) COMMENT '是否注册监控成功'; SET FOREIGN_KEY_CHECKS=1; |
注释和mysql sql 一样,用-- 开头(含空格)
【flyway DDL 数据库数据增量脚本规范】
数据变更脚本通常用于数据字典录入, 配置数据录入,数据库
数据变更脚本按照如下规范命名文件:
文件名规范:
类型 | 格式规范 | 案例 | 备注 |
---|---|---|---|
增量数据DML变更脚本 | VYYYYMMDD__dml-项目迭代版本.sql | V20200730__dml-v3.20.33.sql | 日期后为双下划线 |
增量数据DML变更脚本 | VYYYYMMDD__dml-项目补丁版本.sql | V20200828__dml-v3.20.33.p01.sql | 日期后为双下划线 |
内容规范:
1. 指定数据库名.表名称
2. 如涉及json数据,SQL语句需格式化
INSERT INTO `dict_style` (`DICT_STYLE_ID`, `DICT_STYLE_CODE`, `DICT_STYLE_NAME`, `DICT_STYLE_DESC`, `ENABLE_FLAG`, `CREATED_BY`, `CREATE_DATE`, `LAST_UPDATED_BY`, `LAST_UPDATE_DATE`, `ORG_ID`) VALUES ('46', 'AvailableZone', '{\"en_US\": \"AvailableZone\", \"zh_CN\": \"可用区\"}', '可用区', 'Y', '201704722266', '2020-07-10 10:04:31', '201704722266', '2020-07-24 10:04:31', NULL);
flyway 配置后,在应用启动后,会自动在数据库建立flyway 数据升级脚本版本及升级记录:
表 schema_version
其中升级文件名中的日期就是这里的版本信息。
checksun 是执行脚本的hash编码, 应用启动报flyway 冲突时,依据次编码查询冲突项
suceess, 1表示执行成功, 0表示当前版本执行失败