【问题标题】:Error 1022 - Can't write; duplicate key in table错误 1022 - 无法写入;表中的重复键
【发布时间】:2013-08-06 01:53:36
【问题描述】:

我收到关于 create table 命令重复键的 1022 错误。查看查询后,我无法理解重复发生的位置。其他人可以看到吗?

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 

【问题讨论】:

  • 如果我没记错的话,主键也是一个唯一的索引,所以你必须删除唯一索引语句?
  • ON DELETE NO ACTION 只会放弃外键的全部使用。除非你有非常具体的理由这样做。
  • @AmazingDreams 为什么?它仍然强制执行参照完整性。只有您必须自己删除孩子。这比级联删除更安全,在级联删除中,您可能会通过删除一个不正确的关键字而意外删除大量数据。
  • stackoverflow.com/a/5810024/1567737 为什么在使用'aliased'时使用别名可以立即明确目的?
  • @AmazingDreams 感谢您的提示。我也喜欢围绕它展开的辩论——它帮助我了解利弊。

标签: mysql


【解决方案1】:

您的数据库中很可能已经有一个名为 iduseridcategory 的约束。如果是这样,只需重命名约束即可。

约束对于整个数据库必须是唯一的,而不仅仅是您正在创建/更改的特定表。

要找出当前使用约束的位置,您可以使用以下查询:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');

【讨论】:

  • 正如你所说。在 CREATE 查询的其余部分中,许多约束是使用相同的 idcategory iduser 名称自动生成的 - 感谢您的帮助!
  • 我认为 MySQL Workbench 在导出创建脚本时会解决这个问题,但这就是我在打开项目时“忽略”有关此类事情的警告所得到的。
  • 谢谢你,伙计 :) 这对我很有帮助,现在我的外键约定不同了,我再也不能遇到这个问题了 :)
  • 可以确认。但是如果已经删除了引用的表,但如果命名约束存在,我该怎么办?我可以从不存在的表中删除约束吗?我想我应该从 MySQL 5.6 更新到当前的 MariaDB。
  • 感谢您:整个数据库的约束必须是唯一的
【解决方案2】:

在 MySQL 中更改外键名称。数据库表中不能有相同的外键名称。

检查所有表和所有外键,避免两个外键同名。

【讨论】:

  • 这就是我的问题。我永远不会猜到,你拯救了我的一天。现在使用 fk_id_1、fk_id_2 等。谢谢。
【解决方案3】:

Resolved SuccessfullyNaming Convention这两个链接, 我很容易解决了我面临的同样问题。即,对于外键名称,给出 fk_colName_TableName。此命名约定是明确的,并且还使您的数据库模型中的每个 ForeignKey 都是唯一的,您将永远不会收到此错误。

错误 1022:无法写入;表中的重复键

【讨论】:

    【解决方案4】:

    正如其他人所提到的,您的约束名称可能已被数据库中的另一个表使用。它们在整个数据库中必须是唯一的。

    命名外键约束的一个好的约定是:

    fk_TableName_ColumnName
    

    要调查是否存在可能的冲突,您可以使用此查询列出数据库使用的所有约束:

    SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';
    

    当我运行这个查询时,我发现我之前制作了一个表的临时副本,而这个副本已经在使用我试图使用的约束名称。

    【讨论】:

      【解决方案5】:

      这也可能与 Percona Toolkit 的在线模式更改工具的某些版本中的错误有关。为了对大表进行变异,pt-osc 首先创建一个重复表并将所有记录复制到其中。在某些情况下,某些版本的 pt-osc 2.2.x 会尝试为新表上的约束赋予与旧表上的约束相同的名称。

      在 2.3.0 中发布了一个修复程序。

      更多详情请见https://bugs.launchpad.net/percona-toolkit/+bug/1498128

      【讨论】:

        【解决方案6】:

        我最近 4 个小时都在处理同样的问题。我所做的只是确保约束具有唯一的名称。

        您可以重命名约束。我在我的后面附加了一个数字,这样我就可以轻松追踪出现的次数。

        例子

        如果表中的约束名为boy,外键为X 具有外键 X 的下一个约束可以称为 boy1

        我相信你会比我想出更好的名字。 ?

        【讨论】:

          【解决方案7】:

          我在创建新表时遇到了这个问题。原来我给的外键名已经被使用了。重命名密钥修复了它。

          【讨论】:

            【解决方案8】:

            我也遇到过这个问题。检查Mysql中是否已经存在数据库名,并重命名旧的。

            【讨论】:

              【解决方案9】:

              您可能试图在某个表中创建一个外键,该表在以前存在的表中存在相同的名称。 使用以下格式来命名你的外键

              tablename_columnname_fk
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2019-09-08
                • 1970-01-01
                • 2014-07-01
                • 1970-01-01
                • 1970-01-01
                • 2015-03-02
                • 1970-01-01
                相关资源
                最近更新 更多