बड़ी आईडी मानों से बचने के कारण


17

हम एक वेब एप्लिकेशन पर काम कर रहे हैं, जो अभी तक उपयोगकर्ताओं के लिए सुलभ नहीं है। मेरे मालिक ने देखा कि नए बनाए गए रिकॉर्ड को 10 000 से अधिक की एक आईडी मिलती है, भले ही हमारे पास तालिका में केवल 100 रिकॉर्ड हैं। उसने यह मान लिया कि किसी कारण से वेब इंटरफ़ेस वास्तविक लोगों की तुलना में 100 गुना अधिक अस्थायी रिकॉर्ड बनाता है (और उन्हें हटा देता है) और यह हमें रिलीज के कुछ महीनों के भीतर सीमा से बाहर चलाने के लिए ले जा सकता है।

मुझे नहीं लगता कि वह आईडी मुद्रास्फीति के कारण के बारे में सही है (सहकर्मी जो इस बात का जवाब दे सकता है कि वह छुट्टी पर है, इसलिए हम निश्चित रूप से नहीं जानते हैं), लेकिन चलो मान लेते हैं कि वह है। उसने कहा कि वह एक बिगिनेंट कॉलम का उपयोग करने से घृणा करेगी, और वह हमें आईडी कॉलम को स्वत: सहेजना बंद करने और सर्वर-साइड कोड लिखने के लिए पसंद करेगी, जो पहले "अप्रयुक्त" पूर्णांक को चुनता है और इसे आईडी के रूप में उपयोग करता है।

मैं एक कंप्यूटर विज्ञान स्नातक छात्र थोड़े व्यावहारिक अनुभव के साथ हूं, जो एक जूनियर डेवलपर भूमिका निभाता है। हमारे पास हमारे संगठन के सभी डेटाबेसों को प्रबंधित करने और उनमें से अधिकांश को डिजाइन करने का वर्षों का अनुभव है। मुझे लगता है कि वह इस मामले में गलत है, कि एक बिगिंट आईडी से डरने की कोई बात नहीं है, और यह कि डीबीएमएस की कार्यक्षमता की नकल करने से एंटीपैटर्न की गंध आती है। लेकिन मुझे अभी तक अपने फैसले पर भरोसा नहीं है।

प्रत्येक स्थिति के लिए और उसके खिलाफ क्या तर्क हैं? यदि हम एक बिगिंट का उपयोग करते हैं तो क्या बुरी चीजें हो सकती हैं, और पहिया ऑटोइन्क्रोमिंग कार्यक्षमता को सुदृढ़ करने के खतरे क्या हैं ? क्या कोई तीसरा समाधान है जो किसी एक से बेहतर है? आईडी फेस वैल्यू की मुद्रास्फीति से बचने के लिए उसके क्या कारण हो सकते हैं? मुझे व्यावहारिक कारणों के बारे में भी सुनने में दिलचस्पी है - शायद बिगिंट आईडी सिद्धांत रूप में काम करते हैं, लेकिन व्यवहार में सिरदर्द का कारण बनते हैं?

एप्लिकेशन को बहुत बड़ी मात्रा में डेटा को संभालने की उम्मीद नहीं है। मुझे संदेह है कि यह अगले कुछ वर्षों के भीतर 10 000 वास्तविक रिकॉर्ड तक पहुंच जाएगा।

अगर इससे कोई फर्क पड़ता है, तो हम Microsoft SQL सर्वर का उपयोग कर रहे हैं। एप्लिकेशन C # में लिखा गया है और SQL को Linq का उपयोग करता है।

अपडेट करें

धन्यवाद, मुझे मौजूदा उत्तर और टिप्पणियाँ दिलचस्प लगीं। लेकिन मुझे डर है कि आपने मेरे सवाल को गलत समझा, इसलिए उनमें वही है जो मैं जानना चाहता था।

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

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


SM Ahasan हबीब की पोस्ट codeproject.com/Tips/668042/…
RLF

क्या आप स्पष्ट कर सकते हो? क्या नई आईडी से केवल मूल्यों> 10000 मिलते हैं? या यह है कि नई आईडी में 10000 का अंतराल है? और भविष्य के ऐप के जीवन में कितने आईडी की आवश्यकता होने का अनुमान है?
user2338816

1
पहली अप्रयुक्त आईडी को खोजने के बारे में, बिल कारविन की पुस्तक "एसक्यूएल एंटीपैटर्न" में ठीक इसके बारे में एक अध्याय है। तो हाँ, यह निश्चित रूप से एक एंटीपैटर्न के रूप में देखा जा सकता है!
थॉमस पैड्रॉन-मैक्कार्थी

जवाबों:


24

कोड देखे बिना, यह कहना बहुत कठिन है कि क्या हो रहा है। हालांकि, सबसे अधिक संभावना है कि IDENTITYमूल्य को कैश किया जा रहा है, क्योंकि SQL सर्वर के पुनरारंभ होने के बाद मूल्य में अंतराल हो सकता है। इसके बारे में कुछ अच्छे उत्तरों और जानकारी के लिए /programming/17587094/identity-column-value-suddenly-jumps-to-1001-in-sql-server देखें ।

एक साधारण INTक्षेत्र 2,147,483,647 तक मान रख सकता है। आप वास्तव में मानों को पूर्ण 32 बिट्स देते हुए -2,147,483,648 पर पहचान मूल्य शुरू कर सकते हैं। 4 अरब अलग मूल्य। मुझे संदेह है कि आप उपयोग करने के लिए मानों से बाहर जाने वाले हैं। यह मानते हुए कि आपका आवेदन प्रत्येक वास्तविक पंक्ति के लिए 1,000 मानों का उपभोग कर रहा है, आपको 6 महीने में ID से बाहर निकलने के लिए प्रति दिन लगभग 12,000 पंक्तियाँ बनाने की आवश्यकता होगी, यह मानकर कि आपने IDENTITY0 पर मूल्य प्रारंभ किया था, और एक INT का उपयोग कर रहे थे। यदि आप एक BINTINT का उपयोग कर रहे थे, तो आपको मूल्यों से बाहर भागने से पहले 21 मिलियन शताब्दियों का इंतजार करना होगा यदि आपने प्रति दिन 12,000 पंक्तियों को लिखा है, प्रति पंक्ति 1,000 "मूल्यों" का उपभोग करते हैं।

यह सब कहने के बाद, यदि आप BIGINTपहचान क्षेत्र डेटा प्रकार के रूप में उपयोग करना चाहते हैं, तो निश्चित रूप से इसमें कुछ भी गलत नहीं है। यह आपको सभी इरादों और उद्देश्यों के लिए प्रदान करेगा, उपयोग करने के लिए मूल्यों की असीम आपूर्ति। INT और BIGINT के बीच प्रदर्शन अंतर आधुनिक 64-बिट हार्डवेयर पर व्यावहारिक रूप से गैर-मौजूद है, और NEWID()GUIDs उत्पन्न करने के लिए उदाहरण के लिए अत्यधिक बेहतर है ।

यदि आप आईडी कॉलम के लिए अपने स्वयं के मूल्यों का प्रबंधन करना चाहते हैं, तो आप एक कुंजी तालिका बना सकते हैं, और ऐसा करने के लिए एक बहुत अच्छा बुलेटप्रूफ तरीका प्रदान कर सकते हैं, जो इस प्रश्न के उत्तर में दिखाए गए तरीकों में से एक का उपयोग कर रहा है: बिना एक प्रमुख तालिका के समवर्ती पहुंच को संभालना SQL सर्वर में गतिरोध

अन्य विकल्प, मान लें कि आप SQL सर्वर 2012+ का उपयोग कर रहे हैं, तो SEQUENCEकॉलम के लिए ID मान प्राप्त करने के लिए किसी ऑब्जेक्ट का उपयोग करना होगा । हालाँकि, आपको कैश को नहीं मानने के लिए अनुक्रम को कॉन्फ़िगर करना होगा। उदाहरण के लिए:

CREATE SEQUENCE dbo.MySequence AS INT START WITH -2147483648 INCREMENT BY 1 NO CACHE;

आपके बॉस की "उच्च" संख्याओं की नकारात्मक धारणा के जवाब में, मैं कहूंगा कि इससे क्या फर्क पड़ता है? आप एक का उपयोग मान लिया जाये कि INTएक साथ क्षेत्र, IDENTITY, आप वास्तव में शुरू कर सकता है IDENTITYपर 2147483647और "वेतन वृद्धि" द्वारा मूल्य -1। यह 4 पूरी तरह से स्मृति की खपत, प्रदर्शन, या डिस्क एक 32 बिट संख्या के बाद से इस्तेमाल अंतरिक्ष के लिए कोई अंतर नहीं है बाइट्स, कोई फर्क नहीं पड़ता होगा अगर यह होता है 0या 21474836470बाइनरी में 00000000000000000000000000000000जब एक 32-बिट हस्ताक्षरित INTक्षेत्र में संग्रहीत किया जाता है । 2147483647है01111111111111111111111111111111- दोनों संख्याएँ मेमोरी और डिस्क पर दोनों समान रूप से एक ही स्थान की जगह लेती हैं, और दोनों को प्रोसेस करने के लिए ठीक उसी प्रकार के CPU संचालन की आवश्यकता होती है। किसी महत्वपूर्ण फ़ील्ड में संग्रहीत वास्तविक संख्या के बारे में जानने के लिए अपने एप्लिकेशन कोड को सही तरीके से डिज़ाइन करना अधिक महत्वपूर्ण है।

आपने बड़े-क्षमता वाले ID कॉलम का उपयोग करके या तो (a) के पेशेवरों और विपक्षों के बारे में पूछा, जैसे कि BIGINT, या (b) आईडी अंतराल को रोकने के लिए अपने स्वयं के समाधान को रोल करना। इन चिंताओं का जवाब देने के लिए:

  1. BIGINTINTप्रश्न में कॉलम के लिए डेटा-प्रकार के बजाय । BIGINTकॉलम के लिए ऑन-डिस्क, और इन-मेमरी, दोनों में स्टोरेज की मात्रा का उपयोग करना आवश्यक है। यदि स्तंभ में शामिल तालिका के लिए प्राथमिक कुंजी सूचकांक है, तो तालिका में संलग्न प्रत्येक गैर-संकुल सूचकांक भी BIGINTमान को संग्रहीत करेगा , दो बार के आकार में INT, फिर से मेमोरी और ऑन-डिस्क दोनों में। SQL सर्वर 8KB पृष्ठों में डिस्क पर डेटा संग्रहीत करता है, जहां "पंक्ति" प्रति "पृष्ठ" की संख्या प्रत्येक पंक्ति की "चौड़ाई" पर निर्भर करती है। उदाहरण के लिए, यदि आपके पास 10 स्तंभों वाली एक तालिका है, तो प्रत्येक एक INT, आप लगभग प्रति पृष्ठ 160 पंक्तियों को संग्रहीत करने में सक्षम होंगे। अगर उन स्तंभों जहां बजायBIGINTकॉलम, आप केवल प्रति पृष्ठ 80 पंक्तियों को संग्रहीत करने में सक्षम होंगे। बहुत बड़ी संख्या में पंक्तियों वाली तालिका के लिए, इसका स्पष्ट रूप से मतलब है कि I / O को पढ़ने और लिखने के लिए आवश्यक तालिका किसी भी दी गई संख्या के लिए इस उदाहरण में दोगुनी होगी। दी, यह एक बहुत ही चरम उदाहरण है - यदि आपके पास एक एकल INTया BIGINTस्तंभ और एक कॉलम से मिलकर एक पंक्ति है NCHAR(4000), तो आप प्रति पृष्ठ पर एक पंक्ति में एक ही पंक्ति (सरल) प्राप्त कर सकते हैं, चाहे आपने एक INTया एक का उपयोग किया हो BIGINT। इस परिदृश्य में, यह बहुत सराहनीय अंतर नहीं होगा।

  2. आईडी कॉलम में अंतराल को रोकने के लिए अपने स्वयं के परिदृश्य को रोल करना। आपको अपना कोड इस तरह से लिखना होगा कि "अगली" आईडी मूल्य का उपयोग करने के लिए निर्धारित करना तालिका में होने वाली अन्य क्रियाओं के साथ संघर्ष न करें। SELECT TOP(1) [ID] FROM [schema].[table]भोली की बातों के साथ कुछ समझ में आता है। क्या होगा अगर एक साथ कई अभिनेताओं को टेबल पर नई पंक्तियों को लिखने का प्रयास किया जाए? दो अभिनेता आसानी से एक ही मूल्य प्राप्त कर सकते हैं, जिसके परिणामस्वरूप लेखन-संघर्ष हो सकता है। इस समस्या को हल करने के लिए प्रदर्शन को कम करने, तालिका तक पहुँच को क्रमबद्ध करना आवश्यक है। इस समस्या के बारे में कई लेख लिखे गए हैं; मैं उस विषय पर खोज करने के लिए इसे पाठक पर छोड़ता हूँ।

यहां निष्कर्ष यह है: आपको अपनी आवश्यकताओं को समझने की आवश्यकता है और अपने आवेदन की संगामिति आवश्यकताओं के साथ-साथ दोनों पंक्तियों की संख्या और पंक्ति की चौड़ाई का ठीक से अनुमान लगाएं। हमेशा की तरह, यह ™ निर्भर करता है।


4
+1 लेकिन मैं BIGINT की अंतरिक्ष आवश्यकताओं को नहीं छोड़ेगा। डिस्क पर स्थान के लिए इतना नहीं है, बल्कि I / O और अंतरिक्ष स्मृति में बर्बाद हो गया है। आप डेटा कम्प्रेशन का उपयोग करके इसे बहुत अधिक भरपाई कर सकते हैं, इसलिए जब तक आप 2 बिलियन से ऊपर नहीं जाते हैं, तब तक आप वास्तव में BIGINT प्रकार की कमी महसूस नहीं करते हैं। आदर्श रूप से वे सिर्फ समस्या को ठीक करेंगे (मैं इसे प्रति बग को बग कहने में संकोच करता हूं) - जबकि लोग अंतराल के बारे में परवाह नहीं करते हैं, और जबकि लोगों को दिन में 15 बार अपने सर्वर को फिर से शुरू नहीं करना चाहिए, हमारे पास उन दोनों परिदृश्य हैं काफी प्रचलित, और अक्सर अग्रानुक्रम में।
हारून बर्ट्रेंड

3
बहुत ही मान्य अंक, हारून, हमेशा की तरह। मैं वैसे भी एक INT का उपयोग करने की दिशा में होगा, क्योंकि जब तक वे बड़ी संख्या में पंक्तियों की उम्मीद कर रहे हैं, तब तक BIGINT बहुत अधिक ओवरकिल है।
मैक्स वर्नोन

ID कॉलम के लिए BIGINT डेटा प्रकार का मेमोरी पर बहुत अधिक प्रभाव नहीं पड़ेगा, जब तक कि आपके पास एक ही समय में सैकड़ों या उससे अधिक मेमोरी न हो। फिर भी, यह कुल पंक्ति आकार का एक छोटा सा अंश होने की संभावना है।
user2338816

2
@ user2338816 यह बात है - यदि तालिका बड़ी हो जाती है, तो स्मृति में कई होंगे। और चूंकि पहचान स्तंभ आम तौर पर क्लस्टरिंग कुंजी है, इसलिए यह हर इंडेक्स में प्रत्येक पंक्ति के लिए एक अतिरिक्त 4 बाइट्स भी है। क्या यह हर एक मामले में मायने रखेगा? नहीं। क्या इसे नजरअंदाज किया जाना चाहिए? बिलकुल नहीं। किसी को भी स्केलेबिलिटी के बारे में कोई चीर नहीं लगती है जब तक कि बहुत देर हो चुकी हो।
हारून बर्ट्रेंड

3
यदि आप हालांकि ऐसा एक वैध उम्मीद आप की आवश्यकता हो सकती है bigintकि आप शायद निर्णय लेने से है कि पहले से बजाय पंक्तियों के अरबों के साथ एक मेज के लिए इस जोड़ने के लिए की आवश्यकता होगी, के लिए अपने आप को धन्यवाद करेंगे।
मार्टिन स्मिथ

6

मुख्य कार्य यह करना है कि वर्तमान मूल्य क्यों अधिक है।

SQL2012 से पहले SQL सर्वर संस्करणों के लिए सबसे उचित स्पष्टीकरण - आप एक परीक्षण डेटाबेस के बारे में बात कर रहे हैं- यह होगा कि वहाँ एक सफाई के बाद लोड परीक्षण था।

SQL2012 के साथ सबसे संभावित कारण SQL इंजन के कई रीस्टार्ट होने के कारण शुरू होता है (जैसा कि पहले लिंक मैक्स में दिया गया है)।

यदि अंतर परीक्षण परिदृश्य के कारण होता है, तो मेरे दृष्टिकोण से चिंता करने का कोई कारण नहीं है। लेकिन सुरक्षित पक्ष पर रहने के लिए मैं एक इंजन के पुनः आरंभ होने से पहले और बाद में आवेदन के सामान्य उपयोग के दौरान पहचान मूल्यों की जांच करूंगा।

यह "मज़ेदार" है कि एमएस बताता है कि दोनों विकल्प (या तो झंडे 272 या नई खोज वस्तु का पता लगाते हैं) प्रदर्शन को प्रभावित कर सकते हैं।

यह केवल अगले अगले "सुधार" को कवर करने के लिए सुरक्षित पक्ष पर होने के बजाय बिग का उपयोग करने के लिए सबसे अच्छा समाधान हो सकता है ...


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

2

रुमचो, यदि आप प्रति दिन केवल 1000 पंक्तियां बना रहे हैं, तो यह तय करने के लिए बहुत कम है - पहचान क्षेत्र के साथ INT डेटा प्रकार का उपयोग करें और इसके साथ किया जाए। सरल गणित कहता है कि यदि आप अपने ऐप को 30 साल का जीवनचक्र देते हैं (संभावना नहीं) तो आपके पास प्रति दिन 200,000 पंक्तियाँ हो सकती हैं और फिर भी एक INT डेटा प्रकार की सकारात्मक संख्या सीमा के भीतर हो सकती है।

BigInt का उपयोग करना आपके मामले में ओवरकिल है, यह भी समस्या पैदा कर सकता है यदि आपका ऐप या डेटा ODBC (जैसे Excel या MS एक्सेस, आदि में लाया गया) के माध्यम से एक्सेस किया जाएगा, तो Bigint डेस्कटॉप ऐप्स पर अधिकांश ODBC ड्राइवरों का अच्छी तरह से अनुवाद नहीं करता है।

GUIDS के लिए, अतिरिक्त डिस्क स्थान और अतिरिक्त I / O से अलग, बड़ी समस्या यह है कि वे डिज़ाइन के अनुसार अनुक्रमिक नहीं हैं, इसलिए यदि वे एक सॉर्ट किए गए सूचकांक का हिस्सा हैं, तो आप अच्छी तरह से अनुमान लगा सकते हैं कि प्रत्येक डालने के लिए जा रहा है सूचकांक का सहारा लेने की आवश्यकता है। --Jim


GUIDs के बारे में अच्छी बात, जब तक आप NEWSEQUENTIALID () का उपयोग नहीं करते हैं - मैं अभी भी सहमत हूं, इस प्रश्न में उन्हें स्पष्ट रूप से उपयोग करने का कोई बड़ा कारण नहीं है।
मैक्स वर्नोन

1

प्रयुक्त मूल्यों के बीच एक अंतर है? या शुरुआती मूल्य 10.000 हैं और तब से सभी 1 जोड़ रहे हैं? कभी-कभी यदि संख्या ग्राहकों को दी जाने वाली है, तो शुरुआती संख्या शून्य से अधिक है, मान लीजिए कि उदाहरण के लिए 1500 है, इसलिए ग्राहक को यह एहसास नहीं है कि सिस्टम "नया" है।

स्मालिंट के बजाय बिगिन्ट का उपयोग करने का दोष यह है कि जब बिगिंट "अधिक डिस्क स्थान" का उपयोग करता है, जब डिस्क रीडिंग आप हर डिस्क के लिए कम डिस्क ब्लॉक पढ़ते हैं। यदि आपकी पंक्ति का स्थान छोटा है, तो यह एक खामी हो सकती है, यदि नहीं तो वे ज्यादा मायने नहीं रखते हैं। इसके अलावा, अगर आप एक साथ बहुत सारे संसाधनों के लिए क्वेरी नहीं कर रहे हैं और यदि आपके पास उचित अनुक्रमणिका है, तो यह बहुत ज्यादा मायने नहीं रखता है।

और जैसा कि अन्य प्रतिक्रिया में कहा गया है, यदि आप इंडेक्स से बाहर निकलने के बारे में चिंता करते हैं, तो आपको चिंता नहीं करनी चाहिए, जब तक आपके पास करोड़पति व्यवसाय नहीं होता है तब तक स्मॉलिंटन संभाल नहीं सकता है। "पुनर्प्राप्ति आईडी" के लिए एक तंत्र का आविष्कार करना महंगा है और सॉफ्टवेयर में विफलता अंक और जटिलता जोड़ता है।

सादर


2
ओपी सेवा पुनरारंभ पर अंतराल देख रहा है। यह इस मुद्दे के कारण है । इसके अलावा, मुझे नहीं लगता कि इस काम को बाद में ठीक करने के लिए अल्पावधि में एक अच्छा व्यापार है।
हारून बर्ट्रेंड

@AaronBertrand वास्तव में, मुझे डर है कि दूसरों ने इसे गलत समझा जब उन्होंने इस संभावना का सुझाव दिया। मुझे पूरा यकीन है कि यह उच्च संख्या का कारण नहीं है, लेकिन भले ही यह था, मैं कारण खोजने का प्रयास नहीं कर रहा था, लेकिन यह जानने के लिए कि प्रस्तावित समाधान के लिए क्या तर्क हो सकते हैं और इसके खिलाफ हैं। विवरण के लिए मेरा अपडेट देखें।
रुमचो

@rumtscho वास्तव में यह उत्तर एक अच्छे बिंदु पर प्रकाश डालता है, भले ही यह आपके प्रश्न को सीधे संबोधित न करता हो: "आईडी को पुनर्प्राप्त करने के लिए एक तंत्र का आविष्कार करना महंगा है और सॉफ्टवेयर में विफलता अंक और जटिलता जोड़ता है।"
डॉकटोर जे

@ डॉकटोरेज मैं आपसे सहमत हूं। मैं वह व्यक्ति था जिसने उत्तर को गलत ठहराया :) गलतफहमी को दूर करना चाहता था, इसीलिए मैंने अपनी पहली टिप्पणी छोड़ दी।
रुमचो

1

यदि मैं आपका बॉस था तो मुझे अप्रत्याशित रूप से उच्च आईडी मानों के कारणों में सबसे अधिक दिलचस्पी होगी ... जिस तरह से मैं इसे देखता हूं, आपके द्वारा उल्लिखित दो परिदृश्यों में से प्रत्येक के लिए:

  1. यदि पूर्व परीक्षण में टकराव पहचान मूल्य हैं - तो रिकॉर्ड की अपेक्षित संख्या के बारे में आपकी अन्य टिप्पणियां मुझे एक छोटे से कुंजी प्रकार का सुझाव देने के लिए भी धक्का देंगी। सच कहूं तो अगर मैं अनुक्रम को रीसेट करना संभव था और मौजूदा रिकॉर्ड को फिर से कायम करना चाहता था यदि परीक्षण तालिका के वर्तमान उपयोग के लिए चरित्र से बाहर था (ज्यादातर इस ओवरकिल पर विचार करेगा - 'यह निर्भर करता है')।

  2. यदि मेज पर लिखे अभिलेखों के बहुमत को जल्द ही हटा दिया जाता है, तो मैं इसके बजाय दो तालिकाओं का उपयोग करने पर विचार करना चाहूंगा; एक अस्थायी तालिका जहां रिकॉर्ड लंबे समय तक नहीं रखे जाते हैं, और एक और जहां केवल रिकॉर्ड हम स्थायी रूप से बनाएंगे रखे जाते हैं। फिर से, दीर्घकालिक रिकॉर्ड्स की संख्या के लिए आपकी अपेक्षाएं मुझे आपके प्रमुख कॉलम के लिए एक छोटे प्रकार के उपयोग का सुझाव देती हैं, और प्रति दिन कुछ रिकॉर्ड शायद ही आपको एक प्रदर्शन अंक को एक तालिका से दूसरे तालिका में 'स्थानांतरित' करने का कारण बनेंगे। एक। मुझे संदेह है कि यह आपका परिदृश्य नहीं है, लेकिन कल्पना कीजिए कि एक शॉपिंग वेबसाइट बास्केट / बास्केट को बनाए रखना पसंद कर सकती है और जब एक ऑर्डर वास्तव में रखा जाता है तो डेटा को ऑर्डर / ऑर्डर इटेम सेट में स्थानांतरित कर दिया जाता है।

संक्षेपित करते हुए; मेरी राय में BIGINTs को डरने की आवश्यकता नहीं है, लेकिन स्पष्ट रूप से बहुत से परिदृश्यों के लिए अनावश्यक रूप से बड़े हैं। यदि तालिका कभी बड़ी नहीं होती है, तो आपको कभी भी यह महसूस नहीं होगा कि आपकी पसंद के आधार पर ओवरकिल था ... लेकिन जब आपके पास लाखों पंक्तियों और कई एफके कॉलम हैं जो कि बड़े होते हैं तो वे छोटे होते हैं - तो आप चाहें प्रकारों को अधिक रूढ़िवादी रूप से चयनित किया गया था (न केवल कुंजी कॉलम पर विचार करें, बल्कि सभी मुख्य कुंजी कॉलम और आपके द्वारा रखे गए सभी बैकअप!)। डिस्क स्थान हमेशा सस्ता नहीं होता है (प्रबंधित स्थानों पर सैन डिस्क पर विचार करें - यानी डिस्क स्थान किराए पर है)।

संक्षेप में, मैं कभी-कभी के बजाय हमेशा आपके डेटा प्रकार के चयन पर सावधानीपूर्वक विचार करने के लिए बहस कर रहा हूं । आप हमेशा सही तरीके से उपयोग के पैटर्न की भविष्यवाणी नहीं करेंगे, लेकिन मुझे लगता है कि आप एक नियम के रूप में बेहतर निर्णय लेंगे और हमेशा यह मानेंगे कि 'बड़ा बेहतर है'। सामान्य तौर पर मैं सबसे छोटे प्रकार का चयन करता हूं जिसमें आवश्यक और उचित मूल्य सीमा हो सकती है और मैं खुशी से INT, SMALLINT और यहां तक ​​कि TINYINT पर विचार करूंगा यदि मुझे लगता है कि मूल्य उस प्रकार के योग्य भविष्य के लिए फिट होने की संभावना है। छोटे प्रकारों को हालांकि पहचान की कॉलम के साथ उपयोग करने की संभावना नहीं है, लेकिन खुशी के साथ लुकअप टेबल्स के साथ उपयोग किया जा सकता है जहां प्रमुख मान मैन्युअल रूप से सेट किए जाते हैं।

अंत में, जिन तकनीकों का लोग उपयोग करते हैं, वे उनकी अपेक्षाओं और उत्तरों को काफी हद तक प्रभावित कर सकते हैं। कुछ उपकरण प्रति प्रक्रिया पहचान की पूर्व-बुकिंग श्रेणियों द्वारा श्रेणियों में अंतराल पैदा करने की अधिक संभावना रखते हैं। इसके विपरीत @DocSalvager पूरी तरह से श्रव्य अनुक्रम का सुझाव देता है जो आपके बॉस के दृष्टिकोण को प्रतिबिंबित करता है; मुझे व्यक्तिगत रूप से कभी भी उस स्तर के अधिकार की आवश्यकता नहीं थी - हालांकि सामान्य नियम कि पहचान अनुक्रमिक है और आमतौर पर अंतराल के बिना अक्सर समर्थन स्थितियों और समस्या विश्लेषण में मेरे लिए अविश्वसनीय रूप से उपयोगी रहा है।


1

क्या होगा या तो बिगिन्ट का उपयोग करने या अपना स्वयं का कोड लिखने के लिए और जो कि आईडी (जो एक तरह से पहले से हटाए गए रिकॉर्ड की आईडी का पुन: उपयोग करता है, कोई अंतराल नहीं हैं) को असाइन करेगा?

bigintएक पहचान के रूप में उपयोग करना और अंतराल के साथ रहना:

  • यह सभी अंतर्निहित कार्यक्षमता है
  • आप यह सुनिश्चित कर सकते हैं कि यह आउट-ऑफ-द-बॉक्स काम करेगा
  • यह अंतरिक्ष को बर्बाद करेगा क्योंकि intतब भी आपको लगभग 2M दिनों का डेटा मिलेगा; अधिक पृष्ठों को पढ़ना और लिखना होगा; सूचकांक और गहरे हो सकते हैं। (इन संस्करणों में हालांकि यह एक महत्वपूर्ण चिंता का विषय नहीं है)।
  • एक सरोगेट कुंजी कॉलम अर्थहीन है इसलिए अंतराल ठीक हैं। यदि यह उपयोगकर्ताओं को दिखाया गया है और अंतराल को महत्वपूर्ण माना जाता है तो आप इसे गलत कर रहे हैं।

अपना रोल करें:

  • आपकी विकास टीम हमेशा के लिए सभी विकास और बग फिक्सिंग कार्य कर रही होगी।
  • क्या आप अभी पूंछ में या बीच में भी अंतराल भरना चाहते हैं? बहस करने के लिए डिजाइन निर्णय।
  • प्रत्येक लेखन को समान नई आईडी प्राप्त करने वाली समवर्ती प्रक्रियाओं को रोकने के लिए मजबूत ताले जारी करने होंगे, या टकराव के बाद का समाधान करना होगा ।
  • सबसे खराब स्थिति यदि आप पंक्ति 1 = को हटा दिया जाता है, तो अंतराल को बंद करने के लिए आपको तालिका में प्रत्येक पंक्ति को अपडेट करना होगा। यह समसामयिक और प्रदर्शन को हथौड़ा देगा, सभी कैस्केडिंग विदेशी कुंजी अपडेट्स के साथ क्या होगा।
  • आलसी या उत्सुक अंतर-भरने वाला? जब यह हो रहा है तो समवर्ती क्या होता है?
  • आपको किसी भी लिखने के लिए नई आईडी के लिए पढ़ना होगा = अतिरिक्त भार।
  • कुशल अंतर खोजने के लिए आईडी कॉलम पर एक इंडेक्स की जरूरत होगी।

0

यदि आप वास्तव में अपने पीके के लिए INT की ऊपरी सीमा से टकराने से संबंधित हैं, तो GUID का उपयोग करने पर विचार करें। हां, मुझे पता है कि यह 16 बाइट्स बनाम 4 बाइट्स है, लेकिन डिस्क सस्ती है।

यहाँ पेशेवरों और विपक्ष का एक अच्छा लेखन है


4
+1 क्योंकि यह एक समाधान है, लेकिन आरोन की टिप्पणी को मैक्स के जवाब पर एक कारण के लिए देखें कि "डिस्क सस्ता है" विकल्प को ध्यान से तौले बिना GUID का उपयोग करने का एक कारण नहीं है।
जैक डगलस

1
: यहाँ एक बेहतर लेख एक डेवलपर एक एसक्यूएल सर्वर सूचकांक और स्थापत्य कला विशेषज्ञ के बजाय से है sqlskills.com/blogs/kimberly/disk-space-is-cheap
हारून बर्ट्रेंड

ओह, और निश्चित रूप से NEWID () से पृष्ठ विभाजन से सावधान रहना
मैक्स वर्नोन

1
मेरे बॉस को लगता है कि उच्च मूल्यों के आधार पर ही उन्हें उच्च लग रहा है। मैं उम्मीद कर रहा हूं कि यह प्रश्न मुझे अधिक संभावित आपत्तियां दिखाएगा, लेकिन अगर यह उसके मुख्य तर्कों में से एक है, तो वह शायद GUID के लिए और भी नकारात्मक रूप से प्रतिक्रिया करेगा।
Rumtscho

1
@rumtscho अपने बॉस को बताएं कि एक सरोगेट नंबर सिर्फ एक व्यर्थ संख्या है (संख्या का "आकार" अप्रासंगिक है) और एक क्रम में अंतराल प्राकृतिक और काफी हद तक अपरिहार्य हैं।
हारून बर्ट्रेंड

0

RDBMS प्राथमिक कुंजी (आमतौर पर 'ID' नाम का स्तंभ)
अंतराल को RDBMS स्‍वचालित कॉलम (फ़ील्ड) में टाला नहीं जा सकता। वे मुख्य रूप से अद्वितीय पीके बनाने के लिए अभिप्रेत हैं। प्रदर्शन के लिए, प्रमुख उत्पाद इन्हें बैचों में आवंटित करते हैं, इसलिए विभिन्न सामान्य ऑपरेशन ग्लिट्स के लिए स्वत: पुनर्प्राप्ति तंत्र का उपयोग अप्रयुक्त छोड़ दिया जा सकता है। यह सामान्य बात है।

अखंड अनुक्रम
जब आपको एक अखंड अनुक्रम संख्या की आवश्यकता होती है, जैसे कि उपयोगकर्ताओं द्वारा अक्सर अपेक्षित होता है, तो यह एक अलग कॉलम होना चाहिए जिसे प्रोग्रामेटिक रूप से सौंपा गया है और पीके नहीं होना चाहिए । इस प्रकार, उन 1000 रिकॉर्ड्स में सभी उस कॉलम में समान संख्या में हो सकते हैं।

उपयोगकर्ता अखंड अनुक्रम क्यों चाहते हैं?
किसी भी प्रकार की ऑडिटिंग में त्रुटि के बिना गुम अनुक्रम संख्या सबसे बुनियादी संकेत है। यह "बहीखाता -१०१" सिद्धांत सर्वव्यापी है। हालांकि, हाथ से बनाए गए रिकॉर्ड की छोटी संख्या के लिए क्या काम करता है, डेटाबेस में बहुत बड़ी संख्या में रिकॉर्ड करने पर लागू होने वाली एक गंभीर समस्या है ...

असंबंधित अभिलेखों के लिए प्रमुख मानों का पुन:
उपयोग डेटाबेस को अमान्य करता है "पहले अप्रयुक्त पूर्णांक" का उपयोग करके संभावना का परिचय दिया जाता है कि भविष्य में किसी बिंदु पर, मूल से असंबंधित अभिलेखों के लिए एक संख्या का पुन: उपयोग किया जाएगा। यह डेटाबेस को तथ्यों के सटीक प्रतिनिधित्व के रूप में अविश्वसनीय बनाता है। यह सिद्धांत कारण है कि ऑटोइन्क्रिमेंटिंग मैकेनिज़्म जानबूझकर कभी भी किसी मूल्य का पुन: उपयोग नहीं करने के लिए डिज़ाइन किया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.