เหตุใด 2 แถวจึงได้รับผลกระทบใน "INSERT ... ON DUPLICATE KEY UPDATE"


93

ฉันกำลังทำINSERT ... ON DUPLICATE KEY UPDATEเพื่อPRIMARY KEYในตารางต่อไปนี้:

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

อย่างไรก็ตามแม้ว่าค่าเหล่านี้ควรจะไม่ซ้ำกัน แต่ฉันพบว่า 2 แถวได้รับผลกระทบ

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)

เหตุใดจึงเกิดขึ้น

แก้ไข

สำหรับการเปรียบเทียบโปรดดูข้อความค้นหานี้:

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

เหตุใดคุณจึงมีคีย์หลักสองคีย์ตั้งแต่แรก
Pekka

1
@Pekka PRIMARY KEYเป็น pk เดียวที่สร้างขึ้น(uid, iid)เนื่องจากการสืบค้นส่วนใหญ่จะถูกเรียกใช้เมื่อทราบทั้งสองค่า
Josh Smith

1
@ Josh ฉันเห็น คู่มือดูเหมือนว่าจะท้อมันแม้ว่า: In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.มันไม่จำเป็นต้องเป็นคีย์หลัก? ทำไมไม่เป็นดัชนีปกติ?
Pekka

@Pekka บอกตรงๆไม่แน่ใจ ฉันยังค่อนข้างใหม่สำหรับเรื่องนี้ ดัชนีมีความหมายมากกว่าในกรณีนี้หรือไม่?
Josh Smith

3
@ Josh yup ดัชนีปกติที่ครอบคลุมทั้งสองคอลัมน์ควรจะทำงานได้ดีที่นี่
Pekka

คำตอบ:


202

จากคู่มือ :

ด้วย ON DUPLICATE KEY UPDATE ค่าแถวที่ได้รับผลกระทบต่อแถวคือ 1 ถ้าแถวนั้นถูกแทรกเป็นแถวใหม่และ 2 ถ้าแถวที่มีอยู่ถูกอัพเดต


15
และ 0 ถ้าแถวที่มีอยู่ถูกตั้งค่าเป็นค่าปัจจุบัน
Svish

1
@Svish ขอบคุณ! นี่เป็นประโยชน์จริงๆ
กรีน

2
ฉันแค่สงสัยว่าเหตุผลเบื้องหลังมันคืออะไร .. ชัดเจนว่าอาจส่งคืนเป็นรหัสตอบกลับแทนจำนวนแถวที่ได้รับผลกระทบเพื่อให้สับสนน้อยลง
Sudip Bhandari

... : |. มีวิธีกำหนดจำนวนแถวที่แท้จริงที่ได้รับผลกระทบหรือไม่ แม้ว่าจะมีการอัปเดตแถวที่มีอยู่แล้ว แต่ก็ยังมีเพียงแถวเดียวที่ได้รับผลกระทบ
Ulad Kasach

นี่เหมือนกันสำหรับการแทรกแบตช์ด้วยหรือไม่? … VALUES (2, 2, 'like'), (3, 3, 'like'), (4, 4, 'like') ON DUPLICATE …
luckydonald

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.