2011-11-08 6 views
47

मैं ALTER IGNORE तालिका + एक अद्वितीय कुंजी का उपयोग कर एक MySQL तालिका से डुप्लिकेट को हटाने का प्रयास कर रहा हूं। MySQL दस्तावेज कहता है:MySQL: ALTER IGNORE तालिका "ईमानदारी बाधा उल्लंघन"

आईजीएनओआर मानक एसक्यूएल के लिए एक MySQL एक्सटेंशन है। यह नियंत्रित करता है कि नई तालिका में अद्वितीय कुंजी पर डुप्लीकेट होने पर या सख्त मोड सक्षम होने पर चेतावनियां होने पर वैकल्पिक तालिका कैसे काम करती है। यदि IGNORE निर्दिष्ट नहीं है, तो नकल निरस्त हो जाती है और डुप्लिकेट-कुंजी त्रुटियां होने पर वापस लुढ़का जाता है। यदि IGNORE निर्दिष्ट किया गया है, तो केवल पहली पंक्ति को अद्वितीय कुंजी पर डुप्लिकेट वाले पंक्तियों का उपयोग किया जाता है। अन्य विवादित पंक्तियां हटा दी गई हैं। गलत मूल्य निकटतम मिलान स्वीकार्य मान को छोटा कर दिया जाता है।

जब मैं क्वेरी चलाने ...

ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field) 

... मैं अभी भी त्रुटि # 1062 - कुंजी 'dupidx' के लिए प्रविष्टि 'blabla' डुप्लिकेट।

उत्तर

95

IGNORE MySQL में कीवर्ड एक्सटेंशन को MySQL के कुछ संस्करण पर bug in the InnoDB version लगता है।

तुम हमेशा, MyISAM को परिवर्तित कर सकते हैं, सूचकांक ध्यान न दें-जोड़ने और फिर InnoDB वापस करने के लिए परिवर्तित

ALTER TABLE table ENGINE MyISAM; 
ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field); 
ALTER TABLE table ENGINE InnoDB; 

ध्यान दें, यदि आप विदेशी कुंजी की कमी इस काम नहीं करेगा है, तो आप उन पहले दूर करने के लिए होगा , और बाद में उन्हें वापस जोड़ें।

+56

InnoDB बग उस लिंक में सेट सत्र old_alter_table = 1 पहली बार चलाने के लिए 'एक सुझाव दिया समाधान नहीं है,' इस के लिए काम किया! मुझे। – Peter

+1

धन्यवाद पीटर - यह अब मेरे लिए काम कर रहा है। इस समस्या का कोई ख्याल नहीं था - मेरी देव मशीन मारियाडब है लेकिन जब मुझे उत्पादन पर दौड़ना पड़ा (mysql 5.5) इसमें भाग गया। इस stackoverflow मेरा दिन बचाया! – spidie

+5

यह संभवतः सबसे खराब स्वीकार्य उत्तर है जिसे मैंने कभी स्टैक ओवरफ़्लो पर देखा है। स्टोरेज इंजन बदलना मध्यम आकार के टेबल के साथ ही एक महत्वपूर्ण उपक्रम है। ये तीन प्रश्न संभावित रूप से घंटे के लिए डेटाबेस सर्वर को लॉक कर सकते हैं। यह समाधान की तरह कुछ भी नहीं है। – Mikkel

2

समस्या यह है कि आपके पास उस फ़ील्ड में डुप्लिकेट डेटा है जिसे आप अनुक्रमित करने का प्रयास कर रहे हैं। इससे पहले कि आप एक अद्वितीय इंडेक्स जोड़ सकें, आपको अपमानजनक डुप्लिकेट को हटाना होगा।

एक तरीका यह निम्न करने के लिए है: आप तालिका

+0

नहीं, आईजीएनओआर कीवर्ड को उन डुप्लिकेट का ख्याल रखना चाहिए। यह इस समाधान की सुंदरता होगी। मेरे प्रश्न में उद्धृत दस्तावेज़ देखें। –

25

में केवल अद्वितीय डेटा डालने या सत्र सेट करने की कोशिश करना

CREATE TABLE tmp_table LIKE table; 
    ALTER IGNORE TABLE tmp_table ADD UNIQUE INDEX dupidx (field); 
    INSERT IGNORE INTO tmp_table SELECT * FROM table; 
    DROP TABLE table; 
    RENAME TABLE tmp_table TO table; 

इस अनुमति देता है old_alter_table = 1 (मत भूलना यह स्थापित करने के लिए वापस)

देखें: http://mysqlolyk.wordpress.com/2012/02/18/alter-ignore-table-add-index-always-give-errors/

+2

यह मेरे लिए काम किया। यह बड़ी टेबल पर लंबा है, लेकिन यह काफी रैखिक लगता है। मेरी मशीन पर, यह प्रति घंटे लगभग 2 जीआईबी डेटा संसाधित करने में सक्षम था, जो लगभग दो दिन था। मुझे आश्चर्य है कि यह स्वीकार किए गए समाधान की तुलना में कैसे करता है, जो कि MyISAM में परिवर्तित करना था, इंडेक्स जोड़ें और वापस कन्वर्ट करें। –

+0

सावधान रहें! यदि आप प्रतिकृति का उपयोग कर रहे हैं, तो 'old_alter_table' सेटिंग दोहराना नहीं है, इसलिए' वैकल्पिक तालिका IGNORE 'दास और ब्रेक प्रतिकृति पर असफल हो जाएगी।इसे ठीक करने के लिए, मैंने दास पर 'ALTER' मैन्युअल रूप से प्रदर्शन किया, फिर' सेट ग्लोबल sql_slave_skip_counter = 1' का उपयोग कर अपमानजनक 'वैकल्पिक तालिका' को छोड़ दिया, फिर प्रतिकृति को फिर से शुरू किया। – thenickdude