¿Por qué se ven afectadas 2 filas en mi ʻINSERT ... ON DUPLICATE KEY UPDATE`?

91

Estoy haciendo un INSERT ... ON DUPLICATE KEY UPDATEpor a PRIMARY KEYen la siguiente tabla:

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    |       |
+------------+---------------------------------+------+-----+---------+-------+

Sin embargo, aunque estos valores deberían ser únicos, veo 2 filas afectadas.

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)

¿Por qué está pasando esto?

EDITAR

Para comparar, vea esta consulta:

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
fuente
¿Por qué tienes dos claves principales en primer lugar?
Pekka
1
@Pekka, PRIMARY KEYes un solo pk creado en (uid, iid)ya que la mayoría de las consultas se ejecutarán cuando se conozcan ambos valores.
Josh Smith
1
@Josh ya veo. Sin embargo, el manual parece desalentarlo: In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.¿Debe ser una clave principal? ¿Por qué no un índice normal?
Pekka
@Pekka, honestamente no estoy seguro. Todavía soy relativamente nuevo en esto. ¿Tiene más sentido un índice en este caso?
Josh Smith
3
@Josh sí, un índice normal que abarque ambas columnas debería funcionar bien aquí
Pekka

Respuestas:

201

Del manual :

Con ON DUPLICATE KEY UPDATE, el valor de las filas afectadas por fila es 1 si la fila se inserta como una nueva fila y 2 si se actualiza una fila existente.

Cristóbal
fuente
15
Y 0 si una fila existente se establece en sus valores actuales.
Svish
1
@Svish, ¡Gracias! Esto es realmente útil.
Verde
2
Me pregunto cuál sería la razón detrás de esto ... claramente, podría haber sido devuelto como código de respuesta en lugar del número de filas afectadas para hacerlo menos confuso
Sudip Bhandari
...: |. ¿Hay alguna forma de determinar el número real de filas afectadas? Incluso si se actualiza una fila existente, solo hay una fila afectada
Ulad Kasach
¿Es lo mismo para los insertos por lotes? … VALUES (2, 2, 'like'), (3, 3, 'like'), (4, 4, 'like') ON DUPLICATE …
luckydonald