程序开发数据库版本控制必备 - Flyway
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序开发数据库版本控制必备 - Flyway相关的知识,希望对你有一定的参考价值。
参考技术A在我们日常产品发布的过程中,代码的版本控制可以使用git、svn工具实现。对于数据库每当发布时会出现手动执行sql脚本进行升级数据库,中间经常出现一些漏写、错写情况,对数据库的版本与代码的版本不匹配,导致上线后出现数据库不同步的问题。flyway就是对数据库版本进行控制的工具,可以对不同环境的sql进行迁移操作。
flyway 的官网:https://flywaydb.org/
flyway会对每次执行过sql脚本保存到flyway_schema_history中,在数据库中将保存sql脚本的版本号和对sql生成checksum,当下次执行数据库迁移的时候就会按照版本号从低往高执行。如果以前的版本号脚本已经执行过就不会执行,如果以前版本的sql脚本已经被修改在执行的过程中则会报错。对flyway的详细描述与介绍可以查看flyway的官网。
配置好以上maven组件,在IDEA中就可以看到flyway的快捷插件了。
在插件中undo不能使用,undo为回滚操作。回滚操作只有使用商业版才能使用。
命令行执行
IDEA 工具执行(点击baseline、migrate)
使用migrate必须开头是V+版本号+“_ _“+描述.sql
如V1.0.3_20220618__increment.sql
对已经存在数据库schema结构的数据库的一种解决方案。实现在非空数据库新建metaData flyway_schema_history表,并把Migrations应用到该数据库;也可以在已有表格的数据库中添加metaData数据表。 注:对已有的数据结构的数据库来说,必须要进行baseline,才能进行migrate
清楚掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作再dev和test阶段很好用,但是在生产环境务必禁用。
执行migrate会在指定文件夹下的sql按照版本号依次执行迁移操作。也就是执行sql脚本,对已经执行过的sql脚本便不再执行。
Flyway 一个模式中的多个元数据表
【中文标题】Flyway 一个模式中的多个元数据表【英文标题】:Flyway multiple metadata tables in one schema 【发布时间】:2017-08-23 06:26:54 【问题描述】:我正在尝试使用 Flyway 对模块化应用程序的数据库进行版本控制。每个模块都有自己独立的一组表,以及将控制该组表的版本控制的迁移脚本。
Flyway 允许我为每个模块指定不同的元数据表——这样我可以独立地对每个模块进行版本控制。当我尝试升级应用程序时,我为每个模块运行一个迁移过程,每个模块都有自己的表和一组脚本。请注意,这些表都在同一个架构中。
但是,当我尝试迁移我的应用程序时,第一次迁移是唯一有效的迁移。后续迁移失败,出现以下异常:org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "public" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.
如果我为每个模块手动创建元数据表,每个模块的迁移工作正常。自己创建表格而不是让 Flyway 为我创建表格似乎是解决问题的技巧,而不是解决方案本身。
这是独立管理多组表的有效方法,还是有更好的方法?自己创建元数据表是否有效?
【问题讨论】:
【参考方案1】:对您来说理想的解决方案是将模块拆分为模式。这为您提供了每个模块的有效隔离单元,并且自然适合模块化应用程序(模块完全隔离和自我管理),而不是将所有内容转储到单个模式(尤其是公共模式)中。例如
application_database
├── public
├── module_1
│ ├── schema_version
│ ├── m1_t1
│ └── m1_t2
├── module_2
│ ├── schema_version
│ ├── m2_t1
│ └── m2_t2
...
您的第二个选择是继续使用公共架构来托管所有表,但为每个 schema_version
使用单独的架构。与上面提到的相比,这减少了重构工作,但肯定是一个不那么优雅的设计。例如
application_database
├── public
│ ├── m1_t1
│ ├── m1_t2
│ ├── m2_t1
│ └── m2_t2
├── module_1
│ └── schema_version
│
├── module_2
│ └── schema_version
...
【讨论】:
【参考方案2】:我认为您需要在执行迁移之前为每个模块设置基线。您需要传递 table 选项来覆盖每个模块的 schema_version,例如flyway.table=schema_version_module1
。正如错误消息所暗示的那样,您也可以使用baselineOnMigrate,但是在文档中警告不要这样做 (https://flywaydb.org/documentation/commandline/migrate)。
我们正在考虑使用另一个 schema_version 表的类似方法来应用和记录无法完全推广到每个环境的数据修复。
【讨论】:
以上是关于程序开发数据库版本控制必备 - Flyway的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 集成 Flyway,数据库也能做版本控制,太牛逼了!