Warum sind 2 Zeilen in meinem `INSERT… ON DUPLICATE KEY UPDATE` betroffen?

88

Ich mache eine INSERT ... ON DUPLICATE KEY UPDATEfür eine PRIMARY KEYin der folgenden Tabelle:

DESCRIBE users_interests;
+------------+---------------------------------+------+-----+---------+-------+
| Field      | Type                            | Null | Key | Default | Extra |
+------------+---------------------------------+------+-----+---------+-------+
| uid        | int(11)                         | NO   | PRI | NULL    |       |
| iid        | int(11)                         | NO   | PRI | NULL    |       |
| preference | enum('like','dislike','ignore') | YES  |     | NULL    |       |
+------------+---------------------------------+------+-----+---------+-------+

Obwohl diese Werte eindeutig sein sollten, sind 2 Zeilen betroffen.

INSERT INTO users_interests (uid, iid, preference) VALUES (2, 2, 'like')
ON DUPLICATE KEY UPDATE preference='like';
Query OK, 2 rows affected (0.04 sec)

Warum passiert dies?

BEARBEITEN

Zum Vergleich siehe diese Abfrage:

UPDATE users_interests SET preference='like' WHERE uid=2 AND iid=2;
Query OK, 1 row affected (0.44 sec)
Rows matched: 1  Changed: 1  Warnings: 0
Josh Smith
quelle
Warum haben Sie überhaupt zwei Primärschlüssel?
Pekka
1
@ Pekka, das PRIMARY KEYist ein einzelnes Paket, das erstellt wurde, (uid, iid)da die meisten Abfragen ausgeführt werden, wenn beide Werte bekannt sind.
Josh Smith
1
@ Josh ich verstehe. Das Handbuch scheint jedoch davon abzuraten: In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.Muss es ein Primärschlüssel sein? Warum nicht ein normaler Index?
Pekka
@ Pekka, ehrlich gesagt nicht sicher. Ich bin noch relativ neu in diesem Bereich. Ist ein Index in diesem Fall sinnvoller?
Josh Smith
3
@ Josh yup, ein normaler Index, der beide Spalten umfasst, sollte hier gut funktionieren
Pekka

Antworten:

196

Aus dem Handbuch :

Bei ON DUPLICATE KEY UPDATE beträgt der Wert für betroffene Zeilen pro Zeile 1, wenn die Zeile als neue Zeile eingefügt wird, und 2, wenn eine vorhandene Zeile aktualisiert wird.

ChristopheD
quelle
14
Und 0, wenn eine vorhandene Zeile auf ihre aktuellen Werte gesetzt ist.
Svish
1
@Svish, danke! Das ist wirklich hilfreich.
Grün
1
Ich frage mich nur, was das Grundprinzip dahinter wäre. Es ist klar, dass es als Antwortcode anstelle der Anzahl der betroffenen Zeilen zurückgegeben werden könnte, um es weniger verwirrend zu machen
Sudip Bhandari
...: |. Gibt es eine Möglichkeit, die tatsächliche Anzahl der betroffenen Zeilen zu bestimmen ? Selbst wenn eine vorhandene Zeile aktualisiert wird, ist immer noch nur eine Zeile betroffen
Ulad Kasach
Gilt das auch für Batch-Einsätze? … VALUES (2, 2, 'like'), (3, 3, 'like'), (4, 4, 'like') ON DUPLICATE …
Luckydonald