You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Liquibase为已有数据的表新增自增唯一键报错如何解决

问题原因

  • 你的变更集执行顺序不符合MySQL逻辑:先新增非空且带唯一约束的id列时,MySQL会自动为所有已有记录填充默认值0,多条记录的id都为0直接触发唯一键冲突报错。
  • 自增属性是在列创建完成后才添加的,已经生成的0值不会被自动覆盖,自然不会出现预期的递增效果。

解决方案

调整变更集的执行逻辑,先给列加自增属性,等所有旧行自动填充递增数值后,再补充非空、唯一约束,也可以直接在列定义阶段就指定自增属性,让MySQL在加列时就完成旧行的数值填充。

版本1:精简配置(适配大部分Liquibase版本)

<changeSet author="user" id="1">
    <addColumn tableName="event">
        <column name="id" type="BIGINT" autoIncrement="true">
            <constraints nullable="false" unique="true" uniqueConstraintName="event_id_auto_increment" />
        </column>
    </addColumn>
</changeSet>

版本2:分步配置(兼容老旧版本Liquibase)

如果你的Liquibase版本不支持直接在addColumn中同时指定autoIncrement和约束,可以拆分为多步执行:

<changeSet author="user" id="1">
    <!-- 第一步:先新增无约束的可空id列 -->
    <addColumn tableName="event">
        <column name="id" type="BIGINT" />
    </addColumn>
    <!-- 第二步:添加自增属性,MySQL会自动为所有旧行填充递增的数值 -->
    <addAutoIncrement incrementBy="1" tableName="event" columnName="id" columnDataType="BIGINT" />
    <!-- 第三步:修改列属性,补充非空、唯一约束 -->
    <addNotNullConstraint tableName="event" columnName="id" columnDataType="BIGINT" />
    <addUniqueConstraint tableName="event" columnNames="id" constraintName="event_id_auto_increment" />
</changeSet>

注意事项

  • 如果之前的变更已经执行失败,表中已经生成了全为0的id列,先手动删除该列后再执行新的变更集。
  • 可以给修改后的变更集分配新的id,避免Liquibase因为原变更集已经标记为部分执行而跳过。
  • 如果表数据量很大,建议在业务低峰期执行,避免锁表影响线上服务。

内容的提问来源于stack exchange,提问作者user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:06:01