当没有真正的重复时,在UPDATE上重复输入

我必须更新以下结构的表格:

CREATE TABLE `eav_entity_attribute` (
  `entity_attribute_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Attribute Id',
  `entity_type_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type Id',
  `attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set Id',
  `attribute_group_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Group Id',
  `attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Id',
  `sort_order` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Sort Order',
  PRIMARY KEY (`entity_attribute_id`),
  UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID` (`attribute_set_id`,`attribute_id`),
  UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID` (`attribute_group_id`,`attribute_id`),
  KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER` (`attribute_set_id`,`sort_order`),
  KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID` (`attribute_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Eav Entity Attributes'

上表包含单行:

INSERT INTO `eav_entity_attribute`
(`entity_attribute_id`, `entity_type_id`, `attribute_set_id`, `attribute_group_id`, `attribute_id`, `sort_order`)
VALUES
(32758, 4, 224, 3423, 5171, 12)

我正在运行一个自动导入过程,它将读取外部数据源并写入此表。

此导入运行多次,因此,有时相同的数据会导入多次。 在这种情况下,即使新的旧数据与旧数据相同,该过程也会简单地覆盖旧数据。 使用ON DUPLICATE KEY UPDATE子句处理存在相同数据的情况。 除了这个特定的表格外,这个工作几乎完美。

在此表上,当过程尝试更新时,我收到一个“重复密钥”消息,这是我无法解释的。 我调试了代码,这是失败的查询(从INSERT..ON DUPLICATE KEY提取):

UPDATE eav_entity_attribute
SET 
  `attribute_group_id` = 3423
  ,`attribute_id` = 5171
  ,`attribute_set_id` = 223
  ,`entity_type_id` = 4
  ,`sort_order` = 320
WHERE 
  (`attribute_group_id` = 3423) AND
  (`attribute_id` = 5171)

错误如下:

Error Code: 1062. Duplicate entry '3423-5171' for key 'UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID'

我知道这对3423-5171已经存在,但是UPDATE会自己替换这些值,而不是创建一个新条目。 我对这个问题的原因很困惑,任何建议都会非常受欢迎。 谢谢。

更新 - 新发现

我得到了某种“灵感”,我做了一个实验。 我删除了涉及( attribute_set_idattribute_id )的Unique约束(注意,这不是错误中的那个),我运行了INSERT..ON DUPLICATE查询。 它工作完美。

我是一个猜想,但这是我的想法:我试图写入表中的数据与两个约束冲突:

  • UNIQUE( attribute_set_idattribute_id
  • UNIQUE( attribute_group_idattribute_id
  • INSERT失败,大概是由于第一个约束引发的重复错误。 这会触发UPDATE,它使用第一个约束作为隐式的WHERE子句。 我的推测是,在这种情况下,第一个约束被忽略,但是UPDATE在第二个约束之前跳过,而之前没有涉及。

    对我来说,这对于UPDATE来说似乎并不合适,因为UPDATE会用自己替换某些东西来引发重复的输入错误,但它可能会揭示它背后的逻辑。

    第二次更新

    我发现我正在测试的表中实际上包含了很多行(我忘记禁用过滤视图),这是由于成功导入其他数据导致的。 然而,“重复候选人”在该集合中仍然是独一无二的。

    我确认在注释中发布的内容,表中只包含那些行,INSERT..ON DUPLICATE的作品以及单独的UPDATE。 现在我想知道为什么当表中有更多的数据时表格会变得混乱,因为我们仍然在谈论用相同的数据更新一个唯一的行。

    第三次更新 - 找到根本原因

    我终于找到了UPDATE失败的原因,现在我必须找出如何得到这样的条件。

    线索是我在第一次更新中的猜想。 简单地说,我有两个非常相似的行(请注意,我使用不同的值,因为我从一个干净的数据库开始)。

    row,entity_attribute_id,entity_type_id,attribute_set_id,attribute_group_id,attribute_id,sort_order
    1,16919, 4, 120, 1746, 80, 1
    2,16649, 4, 119, 1744, 80, 210
    

    以下是发生的情况:

  • INSERT尝试插入具有以下值的行: 120, 4, 1744, 80, 54
  • 这触发了“重复键”,因为这些值120, 80是用于字段重复attribute_set_id, attribute_id (行1)。
  • MySQL然后尝试UPDATE,它变成如下所示:

    UPDATE表entity_type_id = 4, attribute_group_id = 1744, sort_order = 54 WHERE( attribute_set_id = 120)AND( attribute_id = 80)

  • 这一次,UPDATE失败,因为值1744,80违反了在第2行中找到的对attribute_group_id, attribute_id的约束。

  • 综上所述

  • INSERT失败,因为第1行的键值attribute_set_id, attribute_id值相同。
  • UPDATE失败,因为第2行的关键字attribute_group_id, attribute_id值相同。
  • 我将不得不审查整个进口程序,因为理论上不应出现此类重复。 MySQL工作正常,数据库很复杂。

    感谢所有的建议。


    尽量不要更新INSERT ... ON DUPLICATE KEY UPDATE UPDATE子句中的键值。 如果具有这些关键字值的记录已经存在,请求MySQL更改关键值是很奇怪的,所以MySQL的意外行为并不令人意外。

    链接地址: http://www.djcxy.com/p/66753.html

    上一篇: Duplicate entry on UPDATE, when there's no real duplicate

    下一篇: Setting up foreign keys in phpMyAdmin?