2010-01-21 12 views
6

मेरे पास 100 मिलियन पंक्तियां हैं, और यह बहुत बड़ी हो रही है। मुझे बहुत सारे अंतराल दिखाई देते हैं। (चूंकि मैं हटाता हूं, जोड़ता हूं, हटाता हूं, जोड़ता हूं।)ऑटो-वृद्धि को रीसेट करने में कोई हानि है?

मैं इन अंतराल को ऑटो-वृद्धि के साथ भरना चाहता हूं। अगर मैं इसे रीसेट करता हूं..क्या कोई हरम है?

मैं ऐसा करते हैं तो यह अंतराल

mysql> ALTER TABLE tbl AUTO_INCREMENT = 1; 
+0

डुप्लिकेट: http://stackoverflow.com/questions/1949842/when-to-fix-auto-increment-gaps-in-mysql – Thilo

उत्तर

9

संभावित बहुत ही खतरनाक, भरना होगा ?: क्योंकि आप पहले से उपयोग किए है फिर से एक नंबर मिल सकता है।

जो आप प्रस्तावित करते हैं वह अनुक्रम को दोबारा रीसेट कर रहा है। यह सिर्फ 1,2,3,4,5,6,7 उत्पादन करेगा, और इसी तरह, इन नंबरों को एक अंतर में नहीं होने पर या नहीं।

अद्यतन: मार्टिन के उत्तर के अनुसार, शामिल खतरों के कारण, MySQL आपको ऐसा करने नहीं देगा। यह कम से कम वर्तमान मूल्य + काउंटर को रीसेट कर देगा।

फिर से सोचें कि अंतराल के अस्तित्व में वास्तविक समस्या क्या है। आमतौर पर यह केवल एक सौंदर्य मुद्दा है।

यदि संख्या बहुत बड़ी हो जाती है, तो बड़े डेटा प्रकार पर स्विच करें (बड़ा होना चाहिए)।

+0

क्या होगा यदि संख्या बहुत बड़ी हो जाए? – TIMEX

+0

यदि संख्या बहुत बड़ी हो जाती है, तो दो मामले होते हैं (दोनों बुरे): अंतराल के कारण यह बहुत बड़ा है, या अंतराल के बिना भी बड़ा है। दूसरे मामले में, कुछ भी नहीं है जो आप अपनी स्कीमा को फिर से सोचने से कम कर सकते हैं। पहले मामले में, आप पूरे कॉलम को छोड़ और फिर से बना सकते हैं। लेकिन यह प्रत्येक पंक्ति को फिर से संख्या देगा, जो प्रश्न से बाहर भी हो सकता है। – Thilo

5

संभावना है कि आपको ऐसा करने से कुछ भी हासिल नहीं होगा, और आप आसानी से पंक्तियों को ओवरराइट करके अपने आवेदन को खराब कर सकते हैं, क्योंकि आप आईडी के लिए गिनती रीसेट करने जा रहे हैं। (दूसरे शब्दों में, अगली बार जब आप कोई पंक्ति डालते हैं, तो यह आईडी 1, और फिर 2 इत्यादि के साथ पंक्ति को ओवरराइट करेगा) अंतराल को भरने से आपको क्या फायदा होगा? यदि संख्या बहुत बड़ी हो जाती है, तो इसे larger number (जैसे BIGINT) में बदलें।


संपादित करें: मैं ठीक किया खड़े हैं। यह कुछ भी नहीं करेगा, जो मेरे बिंदु का समर्थन करता है कि आपको केवल कॉलम के प्रकार को एक बड़े पूर्णांक प्रकार में बदलना चाहिए। BIGINT के लिए अधिकतम संभव मूल्य 2^64 है, जो पर 18 क्विंटिलियन से अधिक है। यदि इस समय आपके पास केवल 100 मिलियन पंक्तियां हैं, तो यह निकट भविष्य के लिए बहुत होना चाहिए।

+0

नहीं, आप कुछ भी ओवरराइट नहीं करेंगे, केवल प्राथमिक कुंजी ऑटो वृद्धि कर सकती हैं, इसलिए यदि आप यह भी कर सकते हैं तो आपको एक डुप्लिकेट कुंजी त्रुटि मिल जाएगी। – Duncan

2

मैं संगीतफ्रैक के साथ सहमत हूं ... एक पूर्णांक के लिए अधिकतम (int(10)) 4,294,967,295 (हस्ताक्षरित ऑफकोर्स) है। यदि आपको और भी अधिक जाने की आवश्यकता है, तो BIGINT पर स्विच करने से आपको 18,446,744,073,709,551,615 तक लाया जाता है।

+0

जब तक आप बहुत सारे डिलीट्स के साथ-साथ सम्मिलन नहीं कर रहे हैं, मुझे लगता है कि आप किसी भी हस्ताक्षरित int से बड़े होने की आवश्यकता होने से पहले डेटाबेस को घुटनों पर लाएंगे। – Duncan

6

FWIW ...MySQL docs

ALTER TABLE tbl AUTO_INCREMENT = 1 

जहां tbl मौजूदा डेटा शामिल हैं को लागू करने का कोई प्रभाव नहीं होना चाहिए के अनुसार:

AUTO_INCREMENT काउंटर नई पंक्तियों के लिए प्रयोग की जाने वाली का मूल्य बदलने के लिए, ऐसा करते हैं:

वैकल्पिक तालिका t2 AUTO_INCREMENT = मान;

आप काउंटर को पर से कम या उसके बराबर मान को रीसेट नहीं कर सकते हैं। MyISAM के लिए, यदि मान से कम या उसके बराबर AUTO_INCREMENT कॉलम में अधिकतम मान है, तो मान वर्तमान अधिकतम प्लस पर रीसेट हो गया है। इनो डीबी के लिए, यदि मान से कम कॉलम में वर्तमान अधिकतम मान है, तो कोई त्रुटि नहीं होती है और वर्तमान अनुक्रम मान परिवर्तित नहीं होता है।

मैंने एक छोटा परीक्षण चलाया जिसने इसे माईसैम तालिका के लिए पुष्टि की।

तो आपके सवालों के जवाब हैं: कोई नुकसान नहीं, और यह अंतराल को भर नहीं पाएगा। जैसा कि अन्य उत्तरदाताओं ने कहा है: डेटा प्रकार का परिवर्तन कम से कम दर्दनाक पसंद की तरह दिखता है।

1

चूंकि आप अगले ऑटो-वृद्धि मूल्य को नहीं बदल सकते हैं, तो आपके पास अन्य विकल्प हैं। डेटाटाइप स्विच किया जा सकता है, लेकिन यह मेरे लिए थोड़ा परेशान प्रतीत होता है क्योंकि आपके पास वास्तव में कई पंक्तियां नहीं हैं। आपको यह सुनिश्चित करना होगा कि आपका कोड उन आईडी को संभाल सकता है जो आपके लिए कठिन हो सकते हैं या नहीं भी हो सकते हैं।

क्या आप बहुत डाउनटाइम कर सकते हैं? यदि आप हैं, तो दो विकल्प हैं जिनके बारे में मैं सोच सकता हूं:

  1. डेटा को डंप/पुनः लोड करें। आप ऐसा कर सकते हैं ताकि यह आईडी नंबर न रखे। उदाहरण के लिए आप एक चयन का उपयोग कर सकते हैं ... डेटा, सैन्स-आईडी को समान डीडीएल के साथ एक नई तालिका में कॉपी करने के लिए। फिर आप पुरानी तालिका छोड़ देते हैं और पुरानी नाम पर नई तालिका का नाम बदलते हैं। इस पर निर्भर करता है कि कितना डेटा है, यह समय (और अस्थायी डिस्क स्थान) के बारे में ध्यान देने योग्य हो सकता है।

  2. आप आईडी बदलने के लिए अद्यतन विवरण जारी करने के लिए एक छोटा प्रोग्राम बना सकते हैं। यदि आप धीरे-धीरे चलते हैं, तो यह समय के साथ आपकी आईडी को "डीफ्रैगमेंट" करेगा। फिर आप अस्थायी रूप से आवेषण को रोक सकते हैं (केवल एक या दो मिनट), अंतिम आईडी अपडेट करें, फिर इसे पुनरारंभ करें। अंतिम आईडी अपडेट करने के बाद आप ऑटो नंबर क्रिएशन वैल्यू को अगले नंबर के रूप में बदल सकते हैं और आपका छेद खत्म हो जाएगा। इससे किसी भी वास्तविक डाउनटाइम (कम से कम इनो डीबी पर) का कारण नहीं बनना चाहिए, लेकिन यह आपके कार्यक्रम के आक्रामक तरीके के आधार पर काफी समय ले सकता है।

बेशक, ये दोनों रेफरेंसियल अखंडता को अनदेखा करते हैं। मुझे लगता है कि यह कोई समस्या नहीं है (लॉग स्टेटमेंट जिन्हें विदेशी कुंजी के रूप में उपयोग नहीं किया जाता है, या कुछ ऐसे)।

0

क्या अंतराल में कोई फर्क पड़ता है?

यदि आप वास्तव में वापस जाना चाहते हैं और उन्हें भरना चाहते हैं, तो आप हमेशा ऑटो वृद्धि को बंद कर सकते हैं, और हर बार जब आप पंक्ति डालना चाहते हैं तो अगली उपलब्ध आईडी के लिए स्कैन करें - दौड़ की स्थिति से बचने के लिए तालिका को लॉक करना याद रखें , बेशक। लेकिन यह बहुत अधिक लाभ के लिए करने के लिए बहुत काम है।

क्या आपको वास्तव में एक सरोगेट कुंजी की आवश्यकता है? डेटा के आधार पर (आपने स्कीमा का उल्लेख नहीं किया है) आप शायद एक प्राकृतिक कुंजी पा सकते हैं।

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

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