liquibase 更改主键粒度
liquibase change primary key granularity
我需要更改 table 以添加一列并将其包含到主键中。
所以我有一个 luiqbase 变更集:
我想知道如何分离关注点并正确实施回滚。
- 在一个变更集中添加列和 PK 变更
<changeSet author="rahul" id="change_pk">
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
</rollback>
</changeSet>
这种方法让我担心的是,如果我无法创建列,我将删除 PK 并重新创建它,这可能会影响数据库响应时间,假设 table 相当大。然而,这使得所有这些更改成为原子。
- 将 PK 变更移动到不同的变更集
<changeSet author="rahul" id="add_col">
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
</changeSet>
<changeSet author="rahul" id="change_pk">
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
</rollback>
</changeSet>
因此我将能够更好地控制 PK 更改的回滚,这将删除并重新创建旧的。但是,有一个问题,当 change_pk
变更集未应用时 - 我有一个列,应该包含在 PK 中,但它没有,使系统容易受到唯一约束违规的影响。
您可以执行以下操作,使用 runAlways attribute. Also, check out different onFail 选项
<changeSet author="rahul" id="add_col" runAlways="true">
<preConditions (perhaps, some non-default onFail option) >
<not>
<columnExists tableName="posts" columnName="aux_id"/>
</not>
</preConditions>
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
</changeSet>
<changeSet author="rahul" id="change_pk">
<preConditions>
<and>
<columnExists tableName="posts" columnName="aux_id"/>
<!-- perhaps some other precondition -->
<sqlCheck expectedResult="id">
SELECT key_column_usage.column_name
FROM information_schema.key_column_usage
WHERE table_schema = SCHEMA()
AND constraint_name = 'PRIMARY'
AND table_name = 'posts'
</sqlCheck>
</and>
</preConditions>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
<dropColumn tableName="posts" columnName="aux_id">
</rollback>
</changeSet>
我需要更改 table 以添加一列并将其包含到主键中。 所以我有一个 luiqbase 变更集:
我想知道如何分离关注点并正确实施回滚。
- 在一个变更集中添加列和 PK 变更
<changeSet author="rahul" id="change_pk">
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
</rollback>
</changeSet>
这种方法让我担心的是,如果我无法创建列,我将删除 PK 并重新创建它,这可能会影响数据库响应时间,假设 table 相当大。然而,这使得所有这些更改成为原子。
- 将 PK 变更移动到不同的变更集
<changeSet author="rahul" id="add_col">
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
</changeSet>
<changeSet author="rahul" id="change_pk">
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
</rollback>
</changeSet>
因此我将能够更好地控制 PK 更改的回滚,这将删除并重新创建旧的。但是,有一个问题,当 change_pk
变更集未应用时 - 我有一个列,应该包含在 PK 中,但它没有,使系统容易受到唯一约束违规的影响。
您可以执行以下操作,使用 runAlways attribute. Also, check out different onFail 选项
<changeSet author="rahul" id="add_col" runAlways="true">
<preConditions (perhaps, some non-default onFail option) >
<not>
<columnExists tableName="posts" columnName="aux_id"/>
</not>
</preConditions>
<addColumn tableName="posts">
<column name="aux_id" type="INT" defaultValue="0"/>
</addColumn>
</changeSet>
<changeSet author="rahul" id="change_pk">
<preConditions>
<and>
<columnExists tableName="posts" columnName="aux_id"/>
<!-- perhaps some other precondition -->
<sqlCheck expectedResult="id">
SELECT key_column_usage.column_name
FROM information_schema.key_column_usage
WHERE table_schema = SCHEMA()
AND constraint_name = 'PRIMARY'
AND table_name = 'posts'
</sqlCheck>
</and>
</preConditions>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
<rollback>
<dropPrimaryKey tableName="posts"/>
<addPrimaryKey tableName="posts" columnNames="id"/>
<dropColumn tableName="posts" columnName="aux_id">
</rollback>
</changeSet>