使用不同 DBMS 的 Liquibase 数据库迁移

Posted

技术标签:

【中文标题】使用不同 DBMS 的 Liquibase 数据库迁移【英文标题】:Database Migration with Liquibase using different DBMS 【发布时间】:2014-10-26 11:18:27 【问题描述】:

我们的客户正在使用 Oracle,我们希望使用 mysql 进行开发。因此我们的 MySQL Scheme 必须与 Oracle 同步。我尝试使用 Liquibase,但在应用变更集时遇到问题,因为数据库特定的 sql 和不同的列类型,如 NUMBER BIGINT 或 VARCHAR VARCHAR2

我是不是用错了这些工具?如何解决这类问题?

【问题讨论】:

【参考方案1】:

Liquibase 将尝试将“varchar”、“int”、“boolean”、“datetime”等标准类型转换为数据库的正确数据类型。如果将列定义为 type="VARCHAR(100)",当您针对 oracle 运行时,它将生成带有 VARCHAR2(100) 的 SQL。

不幸的是,标准类型到数据库特定类型的映射没有得到应有的充分记录。

或者,如果您可以坚持使用 SQL 标准数据类型,它们通常是相当跨数据库的。

当你需要强制一个特定的类型时,你可以像http://www.liquibase.org/documentation/changelog_parameters.html中的例子那样使用一个changelog参数

<column name="notes" type="$clob.type"/>

并为每个数据库定义 clob.type:

<property name="clob.type" value="clob" dbms="oracle"/>
<property name="clob.type" value="longtext" dbms="mysql"/>

【讨论】:

谢谢,但我怎样才能做到这一点?如果我使用 liquibase 更新运行我的变更日志?我必须在每个 chageSet 标签中使用 dbms 标签吗? dbms 标签只是简单地“过滤”变更集以根据目标数据库执行。这很有帮助,但为了减少重复,通常最好尝试让您的变更集尽可能跨数据库。如果您只是将您的列定义为 type="bigint" 或 type="varchar(10)" Liquibase 会将其转换为 oracle 上的 number(38) 和 mysql 上的 bigint,以及 oracle 上的 varchar2(10) 和 varchar(10) mysql。在这种情况下不需要使用 dbms。 感谢您的帮助内森!【参考方案2】:

最好的方法是使用更改日志参数和 dbms 标记。

您可以在变更集的顶部包括:

<property name="autoIncrement" value="true" dbms="mysql"/>
<property name="autoIncrement" value="false" dbms="oracle"/>
<property name="chartype" value="VARCHAR" dbms="mysql"/>
<property name="chartype" value="VARCHAR2" dbms="oracle"/>

然后你可以有这样的变更集: 复制代码

<changeSet id="1" author="a">
    <createTable name="x">
        <column name="id" datatype="int" autoincrement="$autoIncrement"/>
        <column name="name" datatype="$chartype(255)" />
        ....
</changeSet>
<changeSet id="2" author="a" dbms="oracle">
    <createSequence name="seq_x"/>
</changeSet>

编辑来源:http://forum.liquibase.org/topic/auto-increment-vs-sequences-using-liquibase-with-oracle-and-mysql

【讨论】:

以上是关于使用不同 DBMS 的 Liquibase 数据库迁移的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 liquibase modifySQL 子句没有被触发?

Liquibase 和 Spring 如何使用单独的用户进行架构更改

Liquibase - 校验和因不同的数据库供应商而异

在 Liquibase 中指定不同的“TAG”列名

使用 liquibase 将数据从一个数据库复制到另一个数据库

如何忽略 Liquibase diff 中的大小写和数字类型?