Por que 2 linhas são afetadas em meu `INSERT ... ON DUPLICATE KEY UPDATE`?


89

Estou fazendo um INSERT ... ON DUPLICATE KEY UPDATEfor a PRIMARY KEYna seguinte tabela:

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

No entanto, embora esses valores devam ser exclusivos, estou vendo 2 linhas afetadas.

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 que isso está acontecendo?

EDITAR

Para comparação, consulte 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

Por que você tem duas chaves primárias em primeiro lugar?
Pekka

1
@Pekka, PRIMARY KEYé um único pk criado em (uid, iid)uma vez que a maioria das consultas será executada quando ambos os valores forem conhecidos.
Josh Smith

1
@Josh entendo. O manual parece desencorajá-lo: In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.ela precisa ser uma chave primária? Por que não um índice normal?
Pekka

@Pekka, honestamente não tenho certeza. Ainda sou relativamente novo nisso. Um índice faz mais sentido neste caso?
Josh Smith

3
@Josh yup, um índice normal abrangendo ambas as colunas funcionaria bem aqui
Pekka,

Respostas:


198

Do manual :

Com ON DUPLICATE KEY UPDATE, o valor das linhas afetadas por linha é 1 se a linha for inserida como uma nova linha e 2 se uma linha existente for atualizada.


14
E 0 se uma linha existente for definida com seus valores atuais.
Svish

1
@Svish, obrigado! Isso é realmente útil.
Verde de

1
Eu só me pergunto qual seria a razão por trás disso .. claramente, ele poderia ter sido retornado como código de resposta em vez do número de linhas afetadas para torná-lo menos confuso
Sudip Bhandari

...: |. Existe uma maneira de determinar o número real de linhas afetadas? Mesmo se uma linha existente for atualizada, ainda há apenas uma linha afetada
Ulad Kasach

É o mesmo para inserções de lote também? … VALUES (2, 2, 'like'), (3, 3, 'like'), (4, 4, 'like') ON DUPLICATE …
luckydonald

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.