2012-08-30 3 views
15

REPLACE INTO MySQL में फ़ंक्शन इस तरह से काम करता है कि यह पंक्ति को हटा देता है और सम्मिलित करता है। मेरी तालिका में, प्राथमिक कुंजी (id) स्वत: वृद्धि हुई है, इसलिए मैं इसे हटाने की उम्मीद कर रहा था और फिर डेटाबेस की पूंछ पर id के साथ एक तालिका डालें।स्थानांतरित करें, क्या यह प्राथमिक कुंजी का पुनः उपयोग करता है?

हालांकि, यह अप्रत्याशित है और इसे id के साथ सम्मिलित करता है! क्या यह अपेक्षित व्यवहार है, या क्या मुझे यहां कुछ याद आ रहा है? (मैं id जब REPLACE INTO बयान बुला की स्थापना नहीं कर रहा हूँ)

+5

पुन: पेश नहीं कर सकता: 'CREATE TABLE परीक्षण (आईडी INT प्राथमिक कुंजी AUTO_INCREMENT, नाम VARCHAR (20) नहीं NULL अद्वितीय, मूल्य VARCHAR (200) नहीं NULL); परीक्षण (नाम, मूल्य) मूल्यों में बदलें ('foo', 'bar'); परीक्षण (नाम, मूल्य) मूल्यों में बदलें ('foo', 'baz'); परीक्षा से आईडी चुनें; '2 लौटाता है, नहीं 1 - स्पष्ट रूप से' आईडी' दो बार बढ़ाया गया है। (संपादित करें: InnoDB और MyISAM दोनों के साथ परीक्षण किया गया) – lanzz

+0

इस तालिका पर आप किस स्टोरेज इंजन का उपयोग कर रहे हैं? –

+0

जो व्यवहार आप देख रहे हैं वह अपेक्षित व्यवहार के अनुरूप नहीं है। एक संभावित स्पष्टीकरण यह है कि संभवतः एक विदेशी कुंजी बाधा उल्लंघन के कारण, DELETE ऑपरेशन सफल नहीं होता है। यही एकमात्र चीज है जिसके बारे में मैं सोच सकता हूं। अधिक महत्वपूर्ण परीक्षण मामले के बिना मदद करने के लिए और अधिक कुछ नहीं कर सकता है जो मनाए गए व्यवहार को प्रदर्शित करता है। – spencer7593

उत्तर

14

यह एक अपेक्षित व्यवहार है यदि आपके पास अपनी तालिका में UNIQUE अनुक्रमणिका है जो आपके पास अन्यथा हो तो यह पंक्ति को जोड़ देगा जैसा आप उम्मीद करेंगे।

, काम करता है REPLACE वास्तव में सम्मिलित की तरह, सिवाय इसके कि यदि तालिका में एक पुराने पंक्ति प्राथमिक कुंजी या एक अद्वितीय सूचकांक के लिए एक नई पंक्ति जितना समान मान है, पुराने पंक्ति नया पहले हटा दिया जाता है: दस्तावेज़ देखें पंक्ति डाली गई है। खंड 13.2.5, "INSERT सिंटेक्स" देखें।

https://dev.mysql.com/doc/refman/5.5/en/replace.html

यह वास्तव में भी भावना की बहुत बनाता है क्योंकि और कैसे mySQL को बदलने के लिए पंक्ति मिलेगा? यह केवल पूरी तालिका को स्कैन कर सकता है और वह समय लेने वाला होगा। मैं इस प्रदर्शन करने के लिए एक SQL फिडल बनाया, कृपया एक नजर है here

+2

ओपी निर्दिष्ट करता है कि वह 'आईडी' कॉलम के लिए मूल्य प्रदान नहीं कर रहा है। यदि कथन 'आईडी' कॉलम के लिए मूल्य प्रदान कर रहा था, तो हां, हम उम्मीद करेंगे कि मान" पुन: उपयोग "किया जाएगा। लेकिन यदि कोई मूल्य प्रदान नहीं किया जाता है, तो हम सामान्य ऑटोऑक्शन कंटेंट व्यवहार की अपेक्षा करते हैं। – spencer7593

+0

मुझे अपना उत्तर – hol

+1

संपादित करें, वास्तव में, मेरे पास वर्णित एक और 'अद्वितीय' अनुक्रमणिका है जैसा आपने वर्णन किया है। सहायता के लिए बहुत धन्यवाद। :) – matt

3

व्यवहार की उम्मीद है यही कारण है कि। तकनीकी रूप से, उन मामलों में जहां डेटा को प्रतिस्थापित/डालने के लिए सभी अद्वितीय कुंजी (केवल प्राथमिक कुंजी नहीं) एक मौजूदा पंक्ति के लिए एक मिलान हैं, MySQL वास्तव में आपकी मौजूदा पंक्ति को हटा देता है और उसी मान का उपयोग करके प्रतिस्थापन डेटा के साथ एक नई पंक्ति डालता है सभी अद्वितीय कुंजी के लिए। इसलिए, यदि आप ऐसी क्वेरी पर प्रभावित पंक्तियों की संख्या देखना चाहते हैं तो आपको प्रत्येक प्रतिस्थापन के लिए 2 प्रभावित पंक्तियां मिलेंगी और केवल सीधे प्रविष्टियों के लिए ही एक होगी।

+1

यह वास्तव में यह नहीं बताता कि एक आईडी का पुन: उपयोग क्यों किया जाएगा। –

+0

असल में, पूछताछकर्ता (सही) उम्मीद करता है कि उसकी ऑटोइनक्रिकमेंट 'आईडी' को प्रतिस्थापित करने के साथ नया आवंटित किया जाए, लेकिन वह संरक्षित 'आईडी' देखता है। – lanzz

+1

क्या आपके पास एक परीक्षण केस है जो इस व्यवहार को प्रदर्शित करता है? व्यवहार की आपकी व्याख्या मेरे द्वारा अनुभव किए गए व्यवहार के विपरीत है, दोनों MyISAM और InnoDB के साथ। – spencer7593

संबंधित मुद्दे