मैं INSERT...ON DUPLICATE KEY UPDATE
using का उपयोग करने की सलाह दूंगा ।
अगर आप INSERT IGNORE
. का इस्तेमाल करते हैं , तो पंक्ति को वास्तव में सम्मिलित नहीं किया जाएगा यदि इसका परिणाम डुप्लिकेट कुंजी है। लेकिन कथन त्रुटि उत्पन्न नहीं करेगा। यह इसके बजाय एक चेतावनी उत्पन्न करता है। इन मामलों में शामिल हैं:
PRIMARY KEY
के साथ कॉलम में डुप्लीकेट कुंजी डालना याUNIQUE
प्रतिबंध।- एक
NOT NULL
वाले कॉलम में NULL डालना बाधा। - विभाजित तालिका में एक पंक्ति सम्मिलित करना, लेकिन आपके द्वारा सम्मिलित मान किसी विभाजन से मैप नहीं होते हैं।
अगर आप REPLACE
. का इस्तेमाल करते हैं , MySQL वास्तव में एक DELETE
करता है उसके बाद INSERT
आंतरिक रूप से, जिसके कुछ अनपेक्षित दुष्प्रभाव हैं:
- एक नई ऑटो-इन्क्रीमेंट आईडी आवंटित की गई है।
- विदेशी कुंजियों वाली आश्रित पंक्तियों को हटाया जा सकता है (यदि आप कैस्केडिंग विदेशी कुंजियों का उपयोग करते हैं) या फिर
REPLACE
को रोकें । - वे ट्रिगर जो
DELETE
पर सक्रिय होते हैं अनावश्यक रूप से निष्पादित किए जाते हैं। - दुष्प्रभावों को प्रतिकृतियों में भी प्रचारित किया जाता है।
सुधार: दोनों REPLACE
और INSERT...ON DUPLICATE KEY UPDATE
MySQL के लिए विशिष्ट गैर-मानक, मालिकाना आविष्कार हैं। ANSI SQL 2003 एक MERGE
को परिभाषित करता है कथन जो समान आवश्यकता (और अधिक) को हल कर सकता है, लेकिन MySQL MERGE
. का समर्थन नहीं करता है बयान।
एक उपयोगकर्ता ने इस पोस्ट को संपादित करने का प्रयास किया (संपादन मॉडरेटर द्वारा अस्वीकार कर दिया गया था)। संपादन ने यह दावा जोड़ने का प्रयास किया कि INSERT...ON DUPLICATE KEY UPDATE
एक नई ऑटो-इंक्रीमेंट आईडी आवंटित करने का कारण बनता है। यह सच है कि नई आईडी जेनरेट की गई है , लेकिन इसका उपयोग बदली हुई पंक्ति में नहीं किया जाता है।
नीचे प्रदर्शन देखें, Percona Server 5.5.28 के साथ परीक्षण किया गया। कॉन्फ़िगरेशन चर innodb_autoinc_lock_mode=1
(डिफ़ॉल्ट):
mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 10 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
उपरोक्त दर्शाता है कि IODKU कथन डुप्लिकेट का पता लगाता है, और u
के मान को बदलने के लिए अद्यतन को आमंत्रित करता है . AUTO_INCREMENT=3
पर ध्यान दें इंगित करता है कि एक आईडी उत्पन्न हुई थी, लेकिन पंक्ति में उपयोग नहीं की गई थी।
जबकि REPLACE
मूल पंक्ति को हटाता है और एक नई पंक्ति सम्मिलित करता है, जिससे और . उत्पन्न होता है एक नई ऑटो-इन्क्रीमेंट आईडी संग्रहित करना:
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 3 | 20 |
+----+------+