【问题标题】:MySQL duplicate entry error even though there is no duplicate entry即使没有重复条目,MySQL也会出现重复条目​​错误
【发布时间】:2012-10-19 09:52:16
【问题描述】:

我正在使用 MySQL 5.1.56,MyISAM。我的桌子是这样的:

CREATE TABLE IF NOT EXISTS `my_table` (
  `number` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `money` int(11) NOT NULL,
  PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;

它包含这两行:

INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(1, 'S. Name', 150), (2, 'Another Name', 284);

现在我正在尝试插入另一行:

INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(2, 'S. Name', 240);

而 MySQL 在告诉我这个时不会插入它:

#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY'

我真的不明白。主键在前两列(它们都是),所以我尝试插入的行有一个唯一的主键,不是吗?

我尝试修复表,尝试优化表,均无济于事。另请注意,我无法从 MyISAM 更改为 InnoDB。

我是否遗漏了什么或者这是 MySQL 或 MyISAM 的错误?谢谢。

总结并指出我认为问题所在(即使不应该存在): 表在两列上有主键。我正在尝试在这两列中插入具有新值组合的行,但第一列中的值已经在某行中,第二列中的值已经在另一行中。但它们并没有在任何地方结合在一起,所以我相信这应该可以工作,但我很困惑地看到它没有。

【问题讨论】:

  • 那些是 exact 架构和 exact INSERTs?如果没有,我们可能会叫错树!请提供可重现的测试用例。
  • 我的问题是我的INSERT 查询没有指定使用哪个数据库,并且默认数据库有一个同名的表。

标签: mysql primary-key mysql-error-1062 duplicates


【解决方案1】:

您的代码和架构正常。您可能正在尝试使用以前版本的表格。

http://sqlfiddle.com/#!2/9dc64/1/0

您的表甚至没有 UNIQUE,因此该表不可能出现错误。

从该表中备份数据,删除并重新创建。

也许你试图运行CREATE TABLE IF NOT EXIST。它没有被创建,你有旧版本,但是因为IF NOT EXIST没有错误。

您可以像这样运行 SQL 来查看当前的表结构:

DESCRIBE my_table;

编辑 - 稍后添加:

尝试运行这个:

DROP TABLE `my_table`; --make backup - it deletes table

CREATE TABLE `my_table` (
  `number` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `money` int(11) NOT NULL,
  PRIMARY KEY (`number`,`name`),
  UNIQUE (`number`, `name`) --added unique on 2 rows
) ENGINE=MyISAM;

【讨论】:

  • 谢谢,我看到它在那里工作,但我无法让它在我的数据库中工作:(
  • 再次阅读我的答案,我添加了一些信息。
  • 谢谢,我重新创建了表,从旧表中插入数据并再次尝试。没有任何变化,但是在我对新表运行插入查询后,它就起作用了。所以旧表可能以某种方式损坏,即使我不知道是怎么回事。
  • 我没有尝试添加 UNIQUE,它只是重新创建和重新填充表格。
  • A PRIMARY KEY(在 MySQL 中) UNIQUE。所以添加UNIQUE 键是完全多余的(而且是浪费的)。这适用于任何引擎,MyISAM 不一定如此。
【解决方案2】:

我知道在这种情况下这不是问题,但是在创建复合主键时我遇到了类似的“重复条目”问题:

ALTER TABLE table ADD PRIMARY KEY(fieldA,fieldB); 

错误类似于:

#1062 Duplicate entry 'valueA-valueB' for key 'PRIMARY'

于是我搜索了:

select * from table where fieldA='valueA' and fieldB='valueB'

输出只显示 1 行,没有重复!

一段时间后,我发现如果您在这些字段中有 NULL 值,您会收到这些错误。最后,错误消息有点误导我。

【讨论】:

  • 就我而言,我有一个十进制字段,它告诉我我有一个重复的值,但事实并非如此。不过,我确实使用this trick 检查了其他重复值,并确实找到了 3。我解决了这些问题并能够创建索引。
  • NULL 值也是我的情况的原因,在添加 allow nullunique 后有效
【解决方案3】:

我遇到了类似的问题,但在我的例子中,我使用了不区分大小写的排序规则 - utf8_general_ci

因此,当我尝试插入两个在区分大小写的比较中不同但在不区分大小写的比较中相同的字符串时,MySQL 触发了错误,我无法理解这是什么问题,因为我使用了区分大小写的搜索。

解决方案是更改表格的排序规则,例如我使用了utf8_bin,它区分大小写(或者utf8_general_cs 也应该是合适的)。

【讨论】:

    【解决方案4】:

    如果这对 OP 以外的任何人都有帮助,我在使用 InnoDB 时遇到了类似的问题。

    对我来说,真正发生的是外键约束失败。我引用了一个不存在的外键。

    换句话说,错误完全消失了。主键很好,插入外键首先解决了问题。不知道为什么 MySQL 突然出错了。

    【讨论】:

    • MyISAM 不支持 FOREIGN KEYs。任何,没有指定。
    • 抱歉,我忽略了这一点。让我指定 InnoDB 并保留它,以防使用 InnoDB 的任何人遇到这个问题。
    【解决方案5】:

    在我的情况下,错误是由过时的架构引起的,一列最初是 varchar(50),但我尝试导入的转储是从该列具有 varchar(70) 的架构的修改版本创建的(以及一些使用超过 50 个字符的该字段的条目)。

    在导入期间,一些键被截断,截断的版本不再是唯一的。花了一段时间才弄明白,我当时想“但这个所谓的重复键根本不存在!”。

    【讨论】:

    • VARCHAR(50)VARCHAR(70) 足够兼容,因此这不是答案。
    • @RickJames “足够兼容”是什么意思?假设转储有两个键:“my_key_0”和“my_key_1”。如果您将密钥大小减少 1,它们都会变成“my_key_”,从而破坏密钥的唯一性。
    • 如果您的字符串对于数据类型来说太长,它们将被截断。这种数据丢失会导致各种问题。但是如果你所有的字符串都短于 50,那么 (70) 和 (50) 都可以工作,JOINing 会很高兴。
    • @RickJames 好的,我的一些字符串大于 50 并被截断,导致失去唯一性
    • 那么显然“(50)”是一个错误。由于该示例没有长字符串,因此我们在这个问题上陷入了困境。请编辑问题以在示例中使用更长的字符串。或者完全“删除”这个问题。 flag19 == user1763581 ??
    【解决方案6】:

    不太常见的情况,但请记住,根据 DOC https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html

    在运行在线 ALTER TABLE 操作时,运行 ALTER TABLE 操作的线程将应用 DML 操作的“在线日志”,这些操作是从其他连接线程在同一个表上同时运行的。应用 DML 操作时,可能会遇到重复键条目错误(ERROR 1062 (23000): Duplicate entry),即使重复条目只是临时的并且会被“在线日志”中的后续条目恢复.这类似于 InnoDB 中的外键约束检查的想法,其中约束必须在事务期间保持。

    【讨论】:

      【解决方案7】:

      尝试自动递增:

      CREATE TABLE IF NOT EXISTS `my_table` (
         `number` int(11) NOT NULL AUTO_INCREMENT,
         `name` varchar(50) NOT NULL,
         `money` int(11) NOT NULL,
          PRIMARY KEY (`number`,`name`)
      ) ENGINE=MyISAM;
      

      【讨论】:

      • 我不能这样做,'number'列不能有auto_increment。
      【解决方案8】:

      您的代码在此演示中运行良好:

      http://sqlfiddle.com/#!8/87e10/1/0

      我认为您正在执行第二次查询(插入...)两次。试试看

      select * from my_table
      

      在插入新行之前,您会知道您的数据是否已经存在。

      【讨论】:

      • 新行不存在,我查了。
      【解决方案9】:

      我刚试过,如果你有数据和表重建不起作用,只需将表更改为 InnoDB 并重试,它会解决问题

      【讨论】:

        【解决方案10】:

        如果其他人发现这个线程与我的问题有关——我在 MySQL 中使用了“整数”列类型。我试图插入的行有一个主键,其值大于整数允许的值。切换到“bigint”解决了这个问题。

        【讨论】:

        • 他有INT,它允许的范围约为-20亿到20亿。 2 不算太大。
        【解决方案11】:

        根据您的代码,您的“数字”和“名称”是主键,并且您在两行中都插入了 S.NAME,因此会产生冲突。我们正在使用主键来访问完整的数据。在这里,您无法使用主键“名称”访问数据。

        我是初学者,我认为这可能是错误。

        【讨论】:

        • PRIMARY KEY 是两列的组合;所以你的答案不适用。
        【解决方案12】:

        就我而言,这个错误非常具有误导性。问题是当您单击“使唯一”按钮而不是“ALTER IGNORE TABLE”时,PHPMyAdmin 使用“ALTER TABLE”,所以我必须手动进行,例如:

        ALTER TABLE mytbl ADD UNIQUE (columnName);
        

        【讨论】:

          【解决方案13】:

          当添加列或使用现有列作为主键时,通常会出现此问题。由于存在从未实际创建的主键或由于表损坏而未创建它。

          该错误实际上表示的是挂起的键值是空白的。

          解决方案是使用唯一值填充列,然后尝试再次创建主键。 不能有空白、空值或重复值,否则会出现这种误导性错误。

          【讨论】:

            【解决方案14】:

            对我来说,餐桌上的 noop 就足够了(已经是 InnoDB):

            ALTER TABLE $tbl ENGINE=InnoDB;
            

            【讨论】:

              【解决方案15】:

              tl;dr:我的视图显示我的表是空的,但视图排除了现有行。

              我遇到了同样的问题,但我的问题是因为我插入了之前使用过的相同测试行。当我检查我的表是否为空时,我使用了一个排除不同租户的视图,因此搜索结果为空。当我查看实际表时,之前的记录仍然存在。

              一旦我删除了现有记录,插入就起作用了。只输了半天的挫败感……

              【讨论】:

                【解决方案16】:

                在查看您的错误#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY' 时,它表示您在数字字段中使用了主键,这就是它在数字字段上显示重复错误的原因。 所以删除这个主键然后它也插入重复。

                【讨论】:

                • 我真的需要主键在两列上 - 在数字和名称的组合上。我正在尝试插入此主键的新组合,但我的 MySQL 数据库不允许。
                • 您可以使用它在字段编号和名称上放置主键,但是当您在两个名称字段中使用相同的名称时,它会显示重复错误,因此请避免将名称列作为主键。你可以把它不为空。
                • 您写道“它是说您在数字字段中使用主键” - 但事实并非如此。它清楚地显示来自“数字”和“名称”列的值作为主键,并声称它们是重复的,即使它们不是。但我已经解决了,我的桌子可能不知何故损坏了。无论如何感谢您的帮助。
                猜你喜欢
                • 2020-04-26
                • 1970-01-01
                • 2013-03-15
                • 2010-09-18
                • 2019-02-23
                • 1970-01-01
                • 2017-08-15
                • 2020-01-18
                • 1970-01-01
                相关资源
                最近更新 更多