प्राथमिक कुंजी के रूप में UUID या GUID का उपयोग करने के साथ क्या कमियां हैं?


60

मैं एक वितरित प्रणाली का निर्माण करना चाहूंगा। मुझे डेटाबेस में डेटा स्टोर करने की आवश्यकता है और यह कुछ टेबल पर एक प्राथमिक कुंजी के रूप में एक यूयूआईडी या एक गाइड का उपयोग करने के लिए उपयोगी होगा । मुझे लगता है कि यह इस डिजाइन के साथ कमियां है क्योंकि UUID / GUID काफी बड़ी है और वे लगभग यादृच्छिक हैं। इसका विकल्प एक ऑटो-इंक्रीड INT या LONG का उपयोग करना है।

UUID या GUID को मेरी तालिकाओं के लिए एक प्राथमिक कुंजी के रूप में उपयोग करने के साथ क्या कमियां हैं?

मैं शायद DBMS के रूप में डर्बी / JavaDB (क्लाइंट्स पर) और PostgreSQL (सर्वर पर) का उपयोग करूंगा।


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

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

1
मुझे लगता है कि इस पर कुछ अधिक स्पष्ट टिप्पणियों के बिना कि यह "यह निर्भर करता है" सबसे अधिक हो रहा है। उन लोगों के बिना, मैं वीटीसी के लिए जाने वाला हूं।
jcolebrand

एक लेख है जो SQL सर्वर में क्लस्टर इंडेक्स पर GUID बनाम गैर-GUID के बारे में बात करता है जो आपको एक अलग SQL उत्पाद से संबंधित होने पर भी दिलचस्प लग सकता है: x.co/Twpp
Jeff

मैंने देखा कि डर्बी डॉक्टर यूयूआईडी को डेटा प्रकार के रूप में सूचीबद्ध नहीं करता है। आप H2 डेटाबेस इंजन (डर्बी की तरह एक शुद्ध जावा डेटाबेस) जैसे एक विकल्प पर विचार करना चाह सकते हैं जो यूयूआईडी डेटा प्रकार को सूचीबद्ध करता है । बेशक Postgres में UUID मानों को कुशलतापूर्वक संग्रहित करने , अनुक्रमित करने और उत्पन्न करने के लिए उत्कृष्ट समर्थन है ।
बेसिल बॉर्क

जवाबों:


29

यह आपकी पीढ़ी के कार्य और अंतिम तालिकाओं के आकार पर निर्भर करता है

GUID को विश्व स्तर पर विशिष्ट पहचानकर्ता बनाने का इरादा है । जैसा कि Postgres 8.3 दस्तावेज़ीकरण में चर्चा की गई है, ऐसी कोई भी पद्धति नहीं है जो इन पहचानकर्ताओं को उत्पन्न करने के लिए सार्वभौमिक रूप से उपयुक्त है, लेकिन पोस्टग्रेक्यूएल कुछ अधिक उपयोगी उम्मीदवारों के साथ जहाज करता है।

अपनी समस्या के दायरे से, और ऑफ़लाइन की आवश्यकता लिखती है, आपने बहुत करीने से कुछ भी लेकिन एक GUID का उपयोग किया है, और इसलिए अन्य योजनाओं के कोई प्रतिपूरक लाभ नहीं हैं।

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


3
लानत है तुम सो जाओ, तुम चले गए और ब्रायन ने सवाल का जवाब दिया। हां, "ऑफ़लाइन अपडेट" की आवश्यकता ने पूरी अवधारणा को पूरी तरह से बदल दिया।
jcolebrand


1
ऑफ़लाइन-लेखन के साथ भी INT का उपयोग करना संभव होगा। उदाहरण के लिए दो कॉलम का उपयोग करते हुए {Node_ID, Item_ID}जहां प्रत्येक नोड में एक है Node_ID, और Item_IDवह प्रति नोड ऑटो-इंक्रीमेंट है।
जोनास

@ जोनास ~ हाँ, यह संभव है। हालांकि, अधिकांश लोगों में से एक कारण यह भी है कि GUID का चिंतन अन्य डेटाबेस के लिए वैश्विक रूप से अलग-अलग प्रतिकृति के लिए है। मेरा मतलब है कि शब्द ही वहाँ QED है।
jcolebrand

मास्टर / दास आर्किटेक्चर या विरल-कनेक्शन क्लाइंट + मुख्य सर्वर आर्किटेक्चर के संबंध में, क्या मास्टर पर एक Global_id (SERIAL) और एक Global_id (BIGINT) + local_id (SERIAL) का उपयोग करना संभव होगा। गुलाम अपना स्थानीय काम स्थानीय_द का उपयोग करते हुए करते हैं और जब वे मास्टर की ओर कर सकते हैं, तो मास्टर डेटा प्राप्त करता है और इसे एक वैश्विक अनुदान देता है, जिसे वह दास को लौटा देता है, दास ग्लोबल_आईडी क्षेत्र को अपडेट करता है (सर्वर या अन्य से बात करने में संदर्भ उपयोग के लिए) दास)।
मिहाई स्टैंचु

22

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

अब अगर हम कुछ db अहसासों को देखें: 1.) MySQL - प्राथमिक कुंजियों को क्लस्टर किया जाता है, जिसमें व्यवहार बदलने का कोई विकल्प नहीं है - पुनर्संयोजन GUIDs का उपयोग यहां बिल्कुल भी नहीं किया गया है। 2) पोस्टग्रेज, MS-SQL - आप GUID बना सकते हैं प्राथमिक कुंजी बिना रुके, और क्लस्टर इंडेक्स के रूप में एक और क्षेत्र का उपयोग करें, उदाहरण के लिए ऑटोइन्क्रिमेंट इंट।


आप Postgres के लिए जो प्रस्ताव देते हैं, वह MySQL में भी किया जा सकता है, थोड़ा अलग-अलग प्रकार के साथ - auto_increment PK (संकुल कुंजी), GUID अनूठे सूचकांक के साथ (अस्पष्ट)।
ypercube y

यह हमेशा सच नहीं है। डिस्क सिस्टम थ्रूपुट के आधार पर, उस अंतिम पृष्ठ तक पहुंच को सिंक्रनाइज़ करना आपकी अड़चन हो सकती है। blog.kejser.org/2011/10/05/…
mwilson

2
"Microsoft SQL सर्वर के विपरीत, PostgreSQL में एक इंडेक्स पर क्लस्टरिंग उस ऑर्डर को बनाए नहीं रखता है। आपको ऑर्डर को बनाए रखने के लिए CLUSTER प्रक्रिया को फिर से लागू करना होगा।" सूचकांक प्रदर्शन को बेहतर बनाने के लिए
ग्राहक

जानकारी का एक और घनीभूत संस्करण @ बारटोलो-ओटिट से जुड़ा हुआ है: stackoverflow.com/a/4796685/1394233 । यह उत्तर वास्तव में मेरे लिए प्रासंगिक नहीं लगता, क्योंकि यह प्रश्न पीजी के बारे में है और यह SQL सर्वर और MySQL के समान है जो अस्तित्व में नहीं है।
jpmc26

database would need to rearrange all its memory pages to find the right place for insertion=> मुझे नहीं लगता कि Postgres के मामले में ऐसा है, क्योंकि क्लस्टरिंग वैकल्पिक है और नई पंक्तियां अनियंत्रित हैं।
फ्लाविं

3

निर्भर करता है।

गंभीरता से, आपने अब तक जो भी दिया है, यह लगभग उतना ही है जितना आप जा सकते हैं।

यूयूआईडी का उपयोग करना सहायक क्यों होगा? आप INT का उपयोग क्यों नहीं करेंगे? आप बाद में UUIDs पर सिर्फ इंडेक्स क्यों नहीं कर सकते? क्या आप समझते हैं कि UUID की कुंजी के साथ क्रमबद्ध सूची रखने और कुछ मिलियन पंक्तियों के बाद एक यादृच्छिक (गैर-अनुक्रमिक) UUID सम्मिलित करने का क्या मतलब है?

यह किस प्लेटफार्म पर चलेगा? कितने डिस्क? कितने उपयोगकर्ता हैं? कितने रिकॉर्ड?


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

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

1
ऑफ़लाइन टिप्पणी ने सब कुछ बदल दिया। देखें कि अधिक विवरण क्या करता है?
jcolebrand
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.