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

如何在迁移中删除forms表主键id并创建复合主键?

解决删除自增主键并创建复合主键的迁移问题

这个问题我之前也碰到过,根源在于你原来的id列是自增主键,MySQL有个硬性规则:自增列必须被定义为键(主键或唯一键)。你直接删主键的话,id的自增属性还在,但它不再是键了,这就违反了规则,所以触发了1075 Incorrect table definition错误。

下面是正确的迁移步骤和代码:

核心思路

  1. 先移除id列的自增属性,将其改为普通整数列(消除MySQL的规则冲突)
  2. 删除原主键约束
  3. (可选)如果不需要id列,直接删除它
  4. 添加form_id和group_id组成的复合主键

完整迁移代码

public function safeUp()
{
    // 1. 移除id列的自增属性,改为普通整数列
    $this->alterColumn('forms', 'id', $this->integer(11));
    
    // 2. 删除原主键约束(注意:Yii默认创建的主键约束名是`PRIMARY`,不是`id`)
    $this->dropPrimaryKey('PRIMARY', 'forms');
    
    // 可选操作:如果不再需要id列,执行下面的删除语句
    // $this->dropColumn('forms', 'id');
    
    // 3. 添加复合主键,指定约束名为`pk_forms`
    $this->addPrimaryKey('pk_forms', 'forms', ['form_id', 'group_id']);
}

public function safeDown()
{
    // 回滚操作:先删除复合主键
    $this->dropPrimaryKey('pk_forms', 'forms');
    
    // 可选:如果之前删除了id列,需要重新添加主键列
    // $this->addColumn('forms', 'id', $this->primaryKey());
    
    // 否则,恢复id列的自增主键属性
    $this->alterColumn('forms', 'id', $this->primaryKey());
    
    return true;
}

关键注意点

  • 主键约束名:Yii创建主键时,默认的约束名是PRIMARY,而不是字段名id,所以dropPrimaryKey的第一个参数要传PRIMARY,这也是你之前代码可能踩的坑。
  • 复合主键唯一性:执行迁移前,请确保form_id和group_id的组合没有重复值,否则添加复合主键会失败(主键要求唯一)。
  • 数据备份:操作表结构前建议备份数据,避免意外情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:12:11