zoukankan      html  css  js  c++  java
  • Flyway-数据库迁移工具

    一.什么是Flyway?

        Flayway是一款数据库版本控制管理工具,支持数据库版本自动升级,Migrations可以写成sql脚本,也可以写在java代码里;不仅支持Command Line和java api ,也支持Build构建工具和Spring boot,也可以在分布式环境下能够安全可靠安全地升级数据库,同时也支持失败恢复。

        Flyway最核心的就是用于记录所有版本演化和状态的MetaData表,Flyway首次启动会创建默认名为SCHEMA_VERSION的元素局表。 表中保存了版本,描述,要执行的sql脚本等;

       为什么使用Flyway?

          通常在项目开始时会针对数据库进行全局设计,但在开发产品新特性过程中,难免会遇到需要更新数据库Schema的情况,比如:添加新表,添加新字段和约束等,这种情况在实际项目中也经常发生。

        那么,当开发人员完成了对数据库更的SQL脚本后,如何快速地在其他开发者机器上同步?并且如何在测试服务器上快速同步?以及如何保证集成测试能够顺利执行并通过呢?

          假设以Spring Boot技术栈项目为例,可能有人会说,本地使用Hibernate自动更新数据库Schema模式,然后让QA或DEV到测试服务器上手动执行SQL脚本,同时可以写一个Gradle任务自动执行更新。

        个人觉得,对于Hibernate自动更新数据库,感觉不靠谱,不透明,控制自由度不高,而且有时很容易就会犯错,比如:用SQL创建的某个字段为VARCHAR类型,而在Entity中配置的为CHAR类型,那么在运行集成测试时,

        自动创建的数据库表中的字段为CHAR类型,而实际SQL脚本期望的是VARCHAR类型,虽然测试通过了,但不是期望的行为,并且在本地bootRun或服务器上运行Service时都会失败。

        另外,到各测试服务器上手动执行SQL脚本费时费神费力的,干嘛不自动化呢,当然,对于高级别和PROD环境,还是需要DBA手动执行的。最后,写一段自动化程序来自动执行更新,想法是很好的,

        那如果已经有了一些插件或库可以帮助你更好地实现这样的功能,为何不好好利用一下呢,当然,如果是为了学习目的,重复造轮子是无可厚非的。

        其实,以上问题可以通过Flyway工具来解决,Flyway可以实现自动化的数据库版本管理,并且能够记录数据库版本更新记录

    二,怎么使用Flyway(这里使用Springboot整合Flyway)

      1.引入Maven依赖 和 插件(可选,插件是作用是:不需要启动项目就能执行Flyway各种命令)

    <dependency>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-core</artifactId>
                <version>5.0.3</version>
    </dependency>
    <plugin>
                    <groupId>org.flywaydb</groupId>
                    <artifactId>flyway-maven-plugin</artifactId>
                    <version>5.0.3</version>
    </plugin>

      

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

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

      1.   baseline

        对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。

      2.   clean

        清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。

      3.   info

        用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。

      4.   repair

        repair操作能够修复metaData表,该操作在metadata出现错误时很有用。

      5.   undo

        撤销操作,社区版不支持。

      6.   validate

        验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

      2.编辑Flyway相关的配置文件

    server.port=8088
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

      3.在classpath下新建/db/migration文件夹,用于存放SQL脚本

      4.创建我们所需要的并且需要同步数据库的SQL脚本

      注意文件的命名规则:

      这里有两类文件:

        1.仅需要被执行一次的SQL命名以大写的V开头,后面跟上0-9数字的组合,数字之间可以用"."或者下划线"_"分割开,然后在以两个下划线分割,其后跟文件名称,最后以.sql结尾,

         如,V2.1.5__create_user_ddl.sqlV4.1_2__add_user_dml.sql

        2.可重复运行的SQL,则以则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。

        比如,R__truncate_user_dml.sql

        其中,V开头的SQL执行优先级要比R开头的SQL优先级高。

    use testdb;
     
    CREATE TABLE person (
      id int(11) NOT NULL AUTO_INCREMENT,
      first varchar(100) NOT NULL,
      last varchar(100) NOT NULL,
      dateofbirth DATE DEFAULT null,
      placeofbirth varchar(100) not null,
      PRIMARY KEY (id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    insert into person (first,last,dateofbirth,placeofbirth) values('Dursun','KOC', STR_TO_DATE('02/10/1982', '%m/%d/%Y'),'Erzincan');
     
    insert into person (first,last,dateofbirth,placeofbirth) values('Durseeun','KeeOC', STR_TO_DATE('05/10/1982', '%m/%d/%Y'),'Erzeeincan');

    三.Flyway的配置清单

    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

    参考文章:

      https://www.jianshu.com/p/567a8a161641

      https://blog.csdn.net/u014091123/article/details/78133522

      

  • 相关阅读:
    C# json提取多层嵌套到数组-- C# json 数组
    JS中的prototype
    JS_&&||
    js 匿名函数 js-函数定义方法
    js匿名函数确实是个好东西
    JavaScript:undefined!=false之解 及==比较的规则
    Sql 中常用日期转换Convert(Datetime) convert datetime
    jquery设置元素的readonly和disabled
    eWebEditor复制粘贴图片时过滤域名
    java构造函数使用方法总结
  • 原文地址:https://www.cnblogs.com/july-sunny/p/13382836.html
Copyright © 2011-2022 走看看