2011-12-07 17 views
12

को दबाने मैं सटीकMysql अस्थायी रूप से अद्वितीय सूचकांक

+----+-----------+------------+-------------+-------------+-------------+ 
| id | id_parent | sort_order | some_data | other_data | more_data | 
+----+-----------+------------+-------------+-------------+-------------+ 
| 1 |   1 |   1 | lorem ipsum | lorem ipsum | lorem ipsum | 
| 2 |   1 |   2 | lorem ipsum | lorem ipsum | lorem ipsum | 
| 3 |   1 |   3 | lorem ipsum | lorem ipsum | lorem ipsum | 
+----+-----------+------------+-------------+-------------+-------------+ 

अब मैं उन्हें, अपने डेटा और उनके SORT_ORDER में अद्यतन करना चाहते होने के लिए दो स्तंभों पर अद्वितीय सूचकांक, id_parent और SORT_ORDER के साथ एक मेज है एक जाना। sort_order 1 - 2 - 3 से बदल जाएगा, उदाहरण के लिए 2 - 3 - 1

लेकिन जब मैं अपडेट स्टेटमेंट्स चालू करना शुरू करता हूं, तो अद्वितीय इंडेक्स मुझे उम्मीद करता है, जैसा कि उम्मीद है कि मेरे पास id_parent = 1 and sort_order = 2 के साथ दो पंक्तियां नहीं हो सकती हैं। ठीक है, मैं इसे अभी 4 सेट कर सकता हूं, अन्य पंक्तियों को सही क्रम में अपडेट कर सकता हूं, और फिर इसे सेट कर सकता हूं। लेकिन फिर, मुझे एक अतिरिक्त कथन चलाने की ज़रूरत होगी, और शायद अपडेट के सही क्रम को निर्धारित करने के लिए मेरी स्क्रिप्टिंग भाषा में अतिरिक्त तर्क जोड़ें। मैं ओआरएम का भी उपयोग करता हूं, और यह और भी असुविधाजनक हो जाता है।

मेरा प्रश्न अब, क्या mysql अस्थायी रूप से इस अनुक्रमणिका को अनदेखा करने के लिए कुछ तरीका है? एक विशेष लेनदेन शुरू करने की तरह, जिसमें इंडेक्स की गणना करने से पहले ही गणना की जाएगी?

+0

क्या आपकी टेबल InnoDB या MyISAM? – Pacerier

उत्तर

6

जहां तक ​​मुझे पता है कि यह संभव नहीं है।

एकमात्र बार मैंने ऐसा कुछ देखा है कि आप myisam टेबल पर गैर अद्वितीय कुंजी अक्षम कर सकते हैं। लेकिन InnoDB पर नहीं और अद्वितीय कुंजी पर नहीं।

हालांकि, आपको एक अपडेट या दो सहेजने के लिए, सटीक संख्या 1, 2 और 3 की आवश्यकता नहीं है। आपके पास 4, 5 और 6 भी हो सकते हैं। आप इसे किसी क्रम में उपयोग करेंगे और कुछ और नहीं, इसलिए सटीक संख्याएं महत्वपूर्ण नहीं हैं। यदि आप चालाक हैं तो यह आपको एक अपडेट भी बचाएगा। आपके उदाहरण से

update table set sort_order = 4 where sort_order = 1 and id = 1 and id_parent = 1; 

नया सॉर्ट ऑर्डर 2, 3, 1 है और केवल एक अपडेट में।

+1

4-5-6 का उपयोग करके मुझ पर शर्म आती है। – Nameless

+0

कई अपडेट के साथ असंभव होने के बारे में सहमति दें। हालांकि उन्हें एक ही कथन में अपडेट करना काम कर सकता है। किसी भी तरह से, यह एक समाधान के लिए +1 है जो स्पष्ट और सरल है। –

4

'लेकिन जब मैं चल अद्यतन बयान ... शुरू' - मैं समझता हूँ, आप कई अद्यतन कथन का उपयोग, एक पाश में की तरह मान अपडेट करने की कोशिश की। ऐसा क्या? उन्हें एक बार में अपडेट करने के बारे में कैसे? इस तरह, उदाहरण के लिए:

UPDATE atable 
SET sort_order = CASE sort_order WHEN 3 THEN 1 ELSE sort_order + 1 END 
WHERE id_parent = 1 
    AND sort_order BETWEEN 1 AND 3 

एक एकल बयान, परमाणु है, इसलिए समय इस अद्यतन समाप्त होता है, sort_order के मूल्यों से है, हालांकि बदल गया है, अद्वितीय रहते हैं।

मैं माईएसक्यूएल में इसका परीक्षण नहीं कर सकता, क्षमा करें, लेकिन यह निश्चित रूप से SQL सर्वर में काम करता है, और मेरा मानना ​​है कि व्यवहार मानकों का सम्मान करता है।

+0

इस बारे में सोचा नहीं है। यद्यपि ओआरएम के साथ उपयोग करने के लिए दर्द होगा। यह निर्दिष्ट प्रश्न पर सही उत्तर के करीब है, फिर एंड्रियास द्वारा जवाब दिया गया है, लेकिन शायद मैं उसकी सलाह का उपयोग कर समाप्त कर दूंगा। इस मामले में चयनित उत्तर के साथ मुझे क्या करना चाहिए? इसे उत्तर देने के लिए मैं उपयोग करने जा रहा हूं, या उत्तर देने के लिए जो विषय पर करीब है? – Nameless

+0

ठीक है, अगर एक से अधिक उत्तर * प्रश्न * से मेल खाते हैं, तो आपको संभवतः उस * उस समस्या के साथ जाना चाहिए जिसे आप * वास्तविक समस्या * हल करने के लिए लागू करने जा रहे हैं। तो शायद यह एंड्रियास का जवाब है कि आपको चुनना चाहिए। यद्यपि अन्य विचार मौजूद हो सकते हैं। मैं आपके निर्णय के साथ ठीक हूँ, वैसे भी! –

+3

यह तब तक काम नहीं करेगा जब तक कि पंक्तियों को वास्तव में सही क्रम में अपडेट नहीं किया जाता है। निष्पादन के दौरान कोई समय अनूठी कुंजी का उल्लंघन नहीं किया जा सकता है। 'सॉर्टटेस्ट सेट सॉर्ट = सॉर्ट + 1 ऑर्डर सॉर्ट डाउन द्वारा अपडेट करें;' अवरोही क्रम के बिना काम नहीं करेगा, पहली पंक्ति कुंजी का उल्लंघन करेगी, भले ही दूसरी पंक्ति जगह से बाहर हो जाये। –

0

नोट: कुछ टिप्पणियां उल्लेख किया है कि इस सवाल का जवाब नीचे हमेशा अद्वितीय की कमी को दबाने नहीं है, विशेष रूप से InnoDB में। यदि आप इस उत्तर को बेहतर बना सकते हैं, तो कृपया "संपादित करें" पर क्लिक करें और सुधार करें।

आप बस अपनी स्क्रिप्ट के शुरू में इस लाइन जोड़ सकते हैं:

SET FOREIGN_KEY_CHECKS=0; 

UNIQUE_CHECKS चर डॉक्स में बताया गया है:

SET UNIQUE_CHECKS=0; 

यह साथ संयोजन के रूप में इस का उपयोग आम है यहां:
http://dev.mysql.com/doc/refman/5.0/en/converting-tables-to-innodb.html

+2

बस 5.6 पर यह कोशिश की, InnoDB के साथ काम नहीं करता है। डुप्लिकेट कुंजी अभी भी एक त्रुटि फेंक दिया। – bluecollarcoder

+0

@bluecollarcoder क्या आपने * दोनों * 'UNIQUE_CHECKS' और' FOREIGN_KEY_CHECKS' को शून्य पर सेट करने का प्रयास किया था? और क्या आप वाकई * प्राथमिक कुंजी * को डुप्लिकेट नहीं कर रहे हैं, जिसे शायद अभी तक अनुमति नहीं है? –

+1

अद्वितीय कुंजी एक कॉलम पर है जो किसी अन्य तालिका का संदर्भ नहीं देती है, इसलिए 'FOREIGN_KEY_CHECKS' यहां अप्रासंगिक है। और अद्वितीय कुंजी वाला कॉलम निश्चित रूप से प्राथमिक कुंजी का हिस्सा नहीं है। इस मामले में अपेक्षित काम करने के लिए आप किस स्थिति में 'UNIQUE_CHECKS = 0' प्राप्त करने में सक्षम थे? – bluecollarcoder

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