2012-11-22 9 views
16

ich mit der folgenden Struktur, eine Tabelle zu aktualisieren:MySQL 5.5.24 - Duplizieren Eintrag auf AKTUALISIEREN, wenn es keine wirkliche doppelten

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' 

Above Tabelle enthält eine einzelne Zeile:

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) 

Ich führe eine automatische Importprozedur durch, die eine externe Datenquelle liest und in diese Tabelle schreibt.

Dieser Import wird mehrmals ausgeführt und daher werden manchmal dieselben Daten mehrmals importiert. In diesem Fall überschreibt das Verfahren einfach die alten Daten mit der neuen, selbst wenn die neue identisch mit der alten ist. Die Bedingung, in der dieselben Daten vorhanden sind, wird mit einer ON DUPLICATE KEY UPDATE-Klausel behandelt. Dies funktioniert fast perfekt, außer auf dieser speziellen Tabelle.

In dieser Tabelle, wenn die Prozedur einen UPDATE versucht, erhalte ich eine "Duplicate key" Nachricht, die ich nicht erklären kann. Ich gedebuggt den Code, und dies ist die Abfrage, die (von der INSERT..ON DUPLICATE KEY extrahiert) fehlschlägt:

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) 

Der Fehler ist der folgende:

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

Ich weiß, dass das Paar 3423 -5171 existiert bereits, aber das UPDATE würde diese Werte durch sich selbst ersetzen, keinen neuen Eintrag erstellen. Ich bin ziemlich verwirrt über die Ursache dieses Problems, jeder Vorschlag wäre sehr willkommen. Vielen Dank.

Update - Neue Suche

Ich habe eine Art "Inspiration" und ich ein Experiment gemacht. Ich entfernte die Eindeutigkeitseinschränkung mit (attribute_set_id, attribute_id) (beachten Sie, das ist nicht die in dem Fehler), und ich habe die INSERT..ON DUPLICATE-Abfrage ausgeführt. Es hat perfekt funktioniert.

Meins ist eine Vermutung, aber das ist, was ich denke: die Daten Ich versuche, auf die Tabelle Auseinandersetzungen mit zwei Einschränkungen zu schreiben:

  • UNIQUE (attribute_set_id, attribute_id)
  • UNIQUE (attribute_group_id , attribute_id)

die INSERT fehlschlägt, vermutlich aufgrund der Duplizierung Fehler durch die erste constraint angehoben. Dies löst das UPDATE aus, das die erste Einschränkung als implizite WHERE-Klausel verwendet. Meine Spekulation ist, dass in einem solchen Fall die erste Einschränkung irgendwie ignoriert wird, aber das UPDATE stolpert über die zweite, die früher nicht beteiligt war.

Dies scheint mir immer noch kein gültiger Grund für ein UPDATE zu sein, das etwas durch sich selbst ersetzt, um einen doppelten Eingabefehler zu erzeugen, aber es könnte ein wenig Licht in die Logik dahinter werfen.

zweite Update

Ich fand heraus, dass die Tabelle I testete gegen tatsächlich eine Menge Zeilen enthält (Ich habe vergessen, die gefilterte Ansicht zu deaktivieren) aus dem erfolgreichen Import anderer Daten entstehen.Der "Duplikat-Kandidat" ist jedoch immer noch einzigartig in dem Satz.

Ich bestätige, was in den Kommentaren gepostet wird, wenn die Tabelle nur diese Zeilen enthält, das INSERT..ON DUPLICATE funktioniert, sowie das UPDATE allein. Jetzt frage ich mich, warum die Tabelle durcheinander gebracht wird, wenn mehr Daten drin sind, da wir immer noch davon sprechen, dass eine einzige Zeile mit denselben Daten aktualisiert wird.

dritte Update - gefunden, die Ursache

Schließlich fand ich den Grund, warum die Aktualisierung fehlschlägt, jetzt muss ich herausfinden, wie ich in einem solchen Zustand zu bekommen.

Der Hinweis war meine Vermutung in der ersten Aktualisierung. Ich habe einfach zwei sehr ähnliche Zeilen (bitte beachten Sie, dass ich andere Werte verwende, als ich von einer sauberen Datenbank gestartet habe).

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 

Hier ist, was passiert:

  • Die INSERT versucht, eine Zeile mit den folgenden Werten einzufügen: 120, 4, 1744, 80, 54.
  • Dies löst den "doppelten Schlüssel" aus, da die Werte 120, 80 ein Duplikat für die Felder attribute_set_id, attribute_id (Zeile 1) sind.
  • MySQL versucht dann, die aktualisiert werden, die wie folgt wird:

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

  • Dieses Mal schlägt das UPDATE fehl, da die Werte 1744,80 gegen die Einschränkung für das Paar attribute_group_id, attribute_id in Zeile 2 verstoßen.

Zusammengefasst

  • Die INSERT schlägt fehl, da die Zeile 1 die gleichen Werte für den Schlüssel attribute_set_id, attribute_id hat.
  • Das UPDATE schlägt fehl, da Zeile 2 dieselben Werte für den Schlüssel attribute_group_id, attribute_id hat.

Lösung

Ich werde die ganzen Importverfahren, wie es in der Theorie keine dieser Duplikate entstehen sollte haben zu überprüfen. MySQL macht seine Arbeit gut, es ist die Datenbank, die kompliziert ist.

Vielen Dank für alle Vorschläge.

+0

MySQL 5.5.24. Ich habe es dem Titel hinzugefügt. – Diego

+3

Seltsam, arbeitet in 5.5.28. http://sqlfiddle.com/#!2/81569 –

+1

Es funktioniert in 5.5.20 mit den Fragen aus der Frage; Es kommt auf die Größe des Tisches an, nehme ich an. – raina77ow

Antwort

2

Versuchen Sie nicht, Schlüsselwerte innerhalb UPDATE Klausel von INSERT ... ON DUPLICATE KEY UPDATE zu aktualisieren. Es ist merkwürdig, MySQL zu bitten, die Schlüsselwerte zu ändern, wenn bereits ein Datensatz mit diesen Schlüsselwerten existiert. Daher überrascht das unerwartete Verhalten von MySQL nicht.

+0

Die Verwendung von 'ON DUPLICATE KEY UPDATE' führt zu keinem seltsamen Verhalten, das Problem wurde durch eine Reihe von Umständen verursacht und ist nun gelöst. Ich bereite eine vollständige Antwort vor, die es dokumentiert. – Diego

+0

Klingt wie diese Antwort war ziemlich nah! Ein Update auf einen Schlüsselwert innerhalb des Duplicate Key Updates war definitiv der Schuldige. (Ich denke nur, dass sich MySQL unter diesen Umständen erwartungsgemäß verhalten hat) –

Verwandte Themen