2010-06-14 10 views
17

मेरे पास एक डेटाबेस है जहां 2 (या शायद 3 या 4) विभिन्न अनुप्रयोग जानकारी डाल रहे हैं। नई जानकारी में GUID/UUID प्रकार की आईडी है, लेकिन प्रत्येक एप्लिकेशन आईडी उत्पन्न करने के लिए एक अलग एल्गोरिदम का उपयोग कर रहा है। उदाहरण के लिए, कोई NHibernate की "guid.comb" का उपयोग कर रहा है, दूसरा SQLServer के NEWID() का उपयोग कर रहा है, अन्य शायद .NET के Guid.NewGuid() कार्यान्वयन का उपयोग करना चाहते हैं।विभिन्न एल्गोरिदम का उपयोग करके टक्कर जोखिम UUID

क्या आईडी टकराव या डुप्लिकेट का कोई सामान्य जोखिम है?

धन्यवाद!

उत्तर

22

टक्कर का जोखिम थोड़ा ऊपर उठाया गया है लेकिन अभी भी कमजोर है। ग़ौर करें कि:

  • दोनों Comb और NEWID/NEWSEQUENTIALID कुछ एमएस † के लिए नीचे परिशुद्धता के साथ समय स्टांप शामिल। इस प्रकार, जब तक आप पर इन सभी अलग-अलग स्रोतों से पर एक ही पल के समय पर बड़ी संख्या में आईडी उत्पन्न नहीं कर रहे हैं, तो यह सचमुच असंभव आईडी टकराव के लिए है।

  • GUID का हिस्सा टाइमस्टैम्प के आधार पर यादृच्छिक नहीं माना जा सकता है; अधिकांश GUID एल्गोरिदम इन अंकों को पीआरएनजी पर आधारित करते हैं। इस प्रकार, इन अन्य 10 बाइट्स या तो के बीच टकराव की संभावना उसी क्रम पर है जैसे कि आपने दो अलग यादृच्छिक संख्या जनरेटर का उपयोग किया और टकराव के लिए देखा।

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

अब, यह ध्यान रखें कि जब आप Guid.Comb की तरह एक एल्गोरिथ्म का उपयोग, आप केवल uniqueifier, जो 1024 अलग मूल्यों के बराबर की 10 बिट है। इसलिए यदि आप कुछ ही मिलीसेकंड के भीतर बड़ी संख्या में GUID उत्पन्न कर रहे हैं, तो आप टकराव प्राप्त करेंगे। लेकिन यदि आप काफी कम आवृत्ति पर GUID उत्पन्न करते हैं, तो इससे कोई फर्क नहीं पड़ता कि आप एक ही समय में कितने अलग एल्गोरिदम का उपयोग करते हैं, टकराव की संभावना अभी भी व्यावहारिक रूप से कोई नहीं है।

आपके लिए बिल्कुल निश्चित होने का सबसे अच्छा तरीका परीक्षण चलाने के लिए है; सभी 2 या 3 (या फिर भी आप उपयोग करते हैं) GUID उत्पन्न करते हैं, साथ ही, नियमित अंतराल पर, और उन्हें लॉग फ़ाइल में लिखते हैं, और देखें कि क्या आप टकराव प्राप्त करते हैं (और यदि ऐसा है, तो कितने)। इससे आपको एक अच्छा विचार मिलना चाहिए कि यह अभ्यास में कितना सुरक्षित है।

पीएसयदि आप क्लस्टर प्राथमिक कुंजी के लिए GUID उत्पन्न करने के लिए NHibernate के कंघी जनरेटर का उपयोग कर रहे हैं, तो के बजाय NEWSEQUENTIALID() का उपयोग करने पर विचार करें - कंघी का पूरा बिंदु पृष्ठ विभाजन से बचने के लिए है, और आप यह पूरा नहीं कर रहे हैं कि यदि आपके पास गैर- अनुक्रमिक एल्गोरिदम। आपको एक ही कंघी जनरेटर का उपयोग करने के लिए Guid.NewGuid का उपयोग करके किसी भी कोड को भी बदलना चाहिए - एनएचबर्ननेट में उपयोग किया जाने वाला वास्तविक कंघी एल्गोरिदम not complicated है और अपने डोमेन तर्क में डुप्लिकेट करना आसान है।

† ध्यान दें कि NEWID के बारे में कुछ विवाद लगता है, और चाहे इसमें टाइमस्टैम्प हो या नहीं। किसी भी मामले में, चूंकि यह मैक पते पर आधारित है, इसलिए संभव मूल्यों की सीमा V4 GUID या एक कंघी से काफी छोटी है। डेटाबेस के बाहर कंघी GUIDs और NEWSEQUENTIALID डेटाबेस के अंदर चिपकने की सलाह देने के लिए मेरे लिए और कारण।

+0

जबकि मैं (ज्यादातर) आपके निष्कर्ष से सहमत हूं, मुझे कई त्रुटियों को इंगित करना होगा। NEWID में टाइमस्टैंप शामिल नहीं है; और NEWSEQUENTIALID और कंघी से टाइमस्टैम्प अलग-अलग बाइट्स में संग्रहीत होते हैं, इसलिए आप विभिन्न समय पर उत्पन्न "GUIDs" से टकराव प्राप्त कर सकते हैं। इसके अलावा, GUID का उपयोग टाइमस्टैम्प (जैसे कि NEWSEQUENTIALID) का उपयोग * नहीं * बाकी पीआरएनजी संख्याओं के साथ भरें; वे मैक पते का उपयोग करते हैं। यही कारण है कि मैंने एक एकल ग्रिड पीढ़ी एल्गोरिदम पर मानकीकरण का सुझाव दिया। –

+0

@ स्टीफन: मैं साबित नहीं कर सकता कि 'NEWID' टाइमस्टैम्प-आधारित है, क्योंकि दस्तावेज दुर्लभ है, लेकिन AFAIK यह GUID एल्गोरिदम के V1 पर आधारित है जो टाइमस्टैम्प का उपयोग करता है। और कंघी और 'NEWSEQUENTIALID' के लिए टाइमस्टैम्प बाइट एक ही बाइट होना चाहिए, अन्यथा वे वास्तव में अनुक्रमिक नहीं होंगे। (वे टाइम स्टाम्प के लिए विभिन्न आकारों का उपयोग करते हैं, हां, लेकिन छोटा आकार 10 बाइट्स है और इसलिए परिणाम 3.33 एमएस से नीचे प्रविष्टि आवृत्तियों के लिए टकराव मुक्त होगा)। – Aaronaught

+0

वैसे भी, मैंने एक अस्वीकरण जोड़ा है; इस पर ध्यान दिए बिना कि 'NEWID() वास्तव में अपनी आईडी कैसे उत्पन्न करता है, यदि आप क्लाइंट पर कॉम्ब्स का उपयोग करने की योजना बनाते हैं तो सर्वर पर' NEWSEQUENTIALID' का उपयोग करना बेहतर होता है। – Aaronaught

3

हां, जोखिम सामान्य से ऊपर है, क्योंकि ये सभी "GUID" की विभिन्न परिभाषाओं का उपयोग करते हैं। Guid.NewGuid() एक आरएफसी-अनुपालन अधिकतर यादृच्छिक GUID है, लेकिन NEWSEQUENTIALID मैक पता और टाइमस्टैम्प के आधार पर एक पुनर्नवीनीकरण (और इसलिए गैर-आरएफसी-अनुरूप) GUID है, और NHibernate का कंघी GUID पूरी तरह से अलग है (यादृच्छिकता और टाइमस्टैम्प पर आधारित)।

आप केवल एक GUID कार्यान्वयन पर मानकीकरण पर विचार करना चाह सकते हैं। मैं अपने सभी ऐप्स के लिए अपने स्वयं के कॉम्बेड GUID का उपयोग करता हूं। My blog में इन सभी प्रकार के GUIDs के बारे में संक्षिप्त विवरण हैं, साथ ही मेरे लिए डिजाइन निर्णय भी।

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