我需要更新結構如下表:的MySQL 5.5.24 - 上更新重複條目,當沒有真正的重複
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子句處理存在相同數據的情況。除了這個特定的表格外,這個工作幾乎完美。
在此表上,當過程嘗試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_id
,attribute_id
)(注意,這不是錯誤中的那個)的唯一約束,並且我運行了INSERT..ON DUPLICATE查詢。它工作完美。
煤礦是一個猜想,但是這是我的想法:我試圖寫表衝突與兩個約束的數據:
- UNIQUE(
attribute_set_id
,attribute_id
) - UNIQUE(
attribute_group_id
,attribute_id
)
插入失敗可能是因爲由第一約束提出的重複錯誤的。這會觸發UPDATE,它使用第一個約束作爲隱式的WHERE子句。我的推測是,在這種情況下,第一個約束被忽略,但是UPDATE在第二個約束之前跳過,而之前沒有涉及。
對我來說,這仍然不是一個有效的UPDATE的原因,它替代了某些東西來引發重複的輸入錯誤,但它可能會揭示它背後的邏輯。
第二次更新
我發現我是對實際測試表中包含很多行(我忘了關閉過濾視圖)從其他數據成功導入產生。然而,「重複候選人」在該集合中仍然是獨一無二的。
我確認在註釋中發佈了什麼,當表只包含那些行,INSERT..ON DUPLICATE的作品以及單獨的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)和(attribute_id
= 80)這次,UPDATE失敗,因爲值違反了對第012行中的對
attribute_group_id, attribute_id
的限制。
總之
- 插入失敗,因爲第1行具有關鍵
attribute_set_id, attribute_id
相同的值。 - 更新失敗,因爲第2行對於密鑰
attribute_group_id, attribute_id
具有相同的值。
解決方案
我必須檢討整個導入過程,因爲,從理論上講,沒有這樣的複製品應該出現。 MySQL工作正常,數據庫很複雜。
感謝您的所有建議。
MySQL 5.5.24。我將它添加到標題中。 – Diego
奇怪,在5.5.28中工作。 http://sqlfiddle.com/#!2/81569 –
它工作在5.5。20關於這個問題的疑問;我想這裏桌子的大小很重要。 – raina77ow