首页 > 解决方案 > CockroachDB 中 dropIndex 的 CASCADE

问题描述

Liquibase: 以下 liquibase 为删除unq_customer_id约束而写。

 <dropIndex indexName="unq_customer_id"
            schemaName="public"
            tableName="CUSTOMER_LOGIN_EVENT"/>

我使用了 dropIndex,因为CockroachDB通过创建索引来实现唯一约束。CASCADE需要删除此索引。

但是,我不确定如何在上面的 liquibase 脚本中使用级联,因为dropIndexXSD 没有CASCADE.

<xsd:element name="dropIndex">
    <xsd:complexType>
       <xsd:attributeGroup ref="tableNameAttribute"/>
       <xsd:attributeGroup ref="indexName"/>
       <xsd:attribute name="associatedWith" type="xsd:string" use="optional" />
    </xsd:complexType>
</xsd:element> 

错误:

错误:索引“unq_customer_id”被用作唯一约束(如果你真的想删除它,请使用 CASCADE)[失败的 SQL:DROP INDEX public.unq_customer_id]

标签: liquibasecockroachdb

解决方案


直接的答案是,当任何 Liquibase 函数中的逻辑不能满足您的需求时,您的选择是:

  1. <sql>使用标签指定您想要的确切 sql 。这使您可以准确控制将要运行的内容,并允许您使用 Liquibase 访问数据库通过 SQL 公开的任何内容

例子:

<changeSet id="1" author="xyz">
   <sql>DROP INDEX customer_login_event@unq_customer_id cascade</sql>
<changeSet>
  1. 向您的变更集添加一个<modifySql>块。这允许您仍然使用 dropIndex 标记,但调整 SQL。

例子:

<changeSet id="1" author="xyz">
    <dropIndex indexName="unq_customer_id"
               schemaName="public"
               tableName="CUSTOMER_LOGIN_EVENT"/>
    <modifySql>
        <replace replace="unq_customer_id" with="customer_login_event@unq_customer_id"/>
        <append value=" CASCADE"/>
    </modifySql>
</changeSet>

但是,我还要问,在您的情况下,更好的答案是否是编写删除约束而不是索引的脚本?DROP...CASCADE 可能是一个可怕的调用,因为您没有看到/控制实际丢弃的内容。

他们确实通过创建索引来实现约束,但从您的角度来看,这应该只是一个实现细节。如果您最初创建了一个约束,那么更具可读性/可理解性/更安全的事情可能是删除约束,这应该导致 CockroachDB 删除相应的索引,而不是以透明地删除约束的方式删除索引。


推荐阅读