UUID v4 / UUID v7 / ULID की विस्तृत तुलना ─ समयक्रम, दक्षता और पठनीयता में संतुलन कैसे करें
UUID और ULID वितरित सिस्टम तथा डेटाबेस में “वैश्विक रूप से अद्वितीय” ID जारी करने की स्कीमें हैं। पहली नज़र में समान दिखते हैं, लेकिन मानकीकरण, संग्रह दक्षता, मानव-पठनीयता और जानकारी लीक होने के जोखिम में बड़ा फर्क है। यह लेख प्रमुख तीन विकल्पों—UUID v4, UUID v7, और ULID—की तुलना करता है और अंत में UUID v1 तथा UUID v6 पर संक्षिप्त टिप्पणी देता है।
ब्राउज़र में प्रयोग करना चाहते हैं? ये टूल पूरी तरह क्लाइंट-साइड चलते हैं:
- UUID v4 जनरेट करें
- UUID v7 जनरेट करें
- UUID v7 से टाइमस्टैम्प पढ़ें
- ULID जनरेट करें
- ULID से टाइमस्टैम्प पढ़ें
UUID v4: पूरी तरह यादृच्छिक संस्करण
UUID v4 अपने 128 बिट में से 122 बिट शुद्ध रैंडमनेस के लिए रखता है, जिससे टकराव की संभावना नगण्य रहती है। कमी यह है कि ये ID समयक्रम में सॉर्ट नहीं होतीं, इसलिए B-Tree इंडेक्स बार-बार पेज विभाजन झेलते हैं और इंसर्शन लोकैलिटी खराब होती है। v4 को सेशन ID, वन-टाइम टोकन जैसी “खालिस यादृच्छिक” जरूरतों के लिए चुनें।
UUID v7: समयक्रम के साथ विकसित संस्करण
RFC 9562 (2024) में मानकीकृत UUID v7 के शीर्ष 48 बिट UNIX epoch टाइमस्टैम्प (मिलीसेकंड) होते हैं, शेष बिट रैंडमनेस से भरते हैं। स्ट्रिंग तुलना = निर्माण क्रम, इसलिए v7 को प्राइमरी की बनाने पर इंडेक्स लोकैलिटी बनी रहती है। यह मौजूदा uuid
टाइप या BINARY(16)
कॉलम में बिना बदलाव फिट हो जाता है।
- रैंडमनेस बजट: वर्ज़न/वेरिएंट बिट हटाने पर भी लगभग 74 बिट रैंडमनेस बचती है। कुछ इम्प्लीमेंटेशन एक ही मिलीसेकंड में टकराव रोकने हेतु मोनोटोनिक समायोजन करते हैं, फिर भी एंट्रॉपी पर्याप्त होती है।
- सूचना का खुलासा: ID से मिलीसेकंड स्तर का निर्माण समय पता चल जाता है। यदि रैंडमनेस कमजोर हो और निर्गमन दर तेज़ हो तो आस-पास के ID का अनुमान आसान हो सकता है। आंतरिक सिस्टम में यह आमतौर पर स्वीकार्य है, पर सार्वजनिक API में क्रम छिपाना हो तो जोखिम पर विचार करें।
ULID: मानव-अनुकूल ID
ULID (2016) एक डि-फैक्टो मानक बन चुका है। यह Crockford Base32 (26 वर्ण) उपयोग करता है, जिससे O/I/L/1 जैसी मिश्रित होने वाली अक्षर हट जाती हैं—URL और कॉपी-पेस्ट के लिए अनुकूल। v7 की तरह शीर्ष 48 बिट टाइमस्टैम्प (ms) रखते हैं, अतः शब्दकोश क्रम = समयक्रम।
- सॉर्टिंग की गारंटी: Base32 स्ट्रिंग के रूप में ULID हमेशा समयक्रम में तुलना होते हैं (टकराव रोकने के लिए मोनोटोनिक पीढ़ी आम है)।
- भंडारण स्वरूप:
TEXT(26)
में पठनीयता रहती है, लेकिन डेटाबेस में बाइनरी संग्रहीत करने हेतु Base32↔16 बाइट रूपांतरण ज़रूरी है। अधिकांश RDBMS केUUID
टाइप सीधे ULID नहीं ले पाते। - सूचना का खुलासा: v7 की तरह ULID भी टाइमस्टैम्प (ms) उजागर करता है। यदि आप API उपभोक्ताओं को निर्गमन क्रम बताना नहीं चाहते तो अन्य विकल्प देखें।
तुलना तालिका (व्यावहारिक दृष्टि)
पहलू | UUID v4 | UUID v7 | ULID |
---|---|---|---|
मानकीकरण | RFC 4122 | RFC 9562 (2024) | डि-फैक्टो, औपचारिक मानक नहीं |
बिट लेआउट | 128 बिट, जिनमें 122 बिट रैंडम | 48-बिट UNIX ms + शेष रैंडम (मोनोटोनिक वैकल्पिक) |
48-बिट UNIX ms + 80-बिट रैंडम |
रैंडम एंट्रॉपी | ≈122 बिट | ≈74 बिट (वर्ज़न/वेरिएंट हटाकर) | 80 बिट |
स्ट्रिंग रूप | 36 वर्ण (हेक्स + हाइफ़न) | 36 वर्ण (हेक्स + हाइफ़न) | 26 वर्ण (Crockford Base32) |
प्राकृतिक क्रम (टेक्स्ट) | ✗ (रैंडम) | ✓ (शब्दकोश क्रम = समयक्रम) | ✓ (शब्दकोश क्रम = समयक्रम) |
प्राकृतिक क्रम (बाइनरी) | ✗ | ✓ (BINARY(16) की तुलना समयक्रम में होती है) |
✓ (यदि 6-बाइट टाइमस्टैम्प को बिग-एंडियन रखकर बाकी रैंडम) |
डेटाबेस में अनुकूलता | uuid / BINARY(16) आदर्श |
uuid / BINARY(16) आदर्श |
TEXT(26) पठनीय; BINARY(16) हेतु रूपांतरण और कई UUID टाइप अस्वीकार |
इंडेक्स लोकैलिटी | कमजोर (रैंडम इंसर्शन से गर्म क्षेत्र) | अच्छी (एपेंड-फ्रेंडली, फिर भी हॉट-स्पॉट सम्भव) | अच्छी (एपेंड-फ्रेंडली, वही सावधानियाँ) |
समानता जाँच लागत | कम (16-बाइट तुलना) | कम (16-बाइट तुलना) | TEXT तुलना महँगी; BINARY में कम |
एन्कोडिंग ओवरहेड | हेक्स↔16 बाइट (हल्का) | हेक्स↔16 बाइट (हल्का) | Base32↔16 बाइट (भारी) |
मानव-पठनीयता / URL अनुकूलता | कम | कम | ऊँची |
जानकारी का खुलासा | नहीं | टाइमस्टैम्प (ms) | टाइमस्टैम्प (ms) |
टिपिकल उपयोग | सेशन ID, वन-टाइम की | डेटाबेस प्राइमरी की, इवेंट ID, लॉग क्रम | सार्वजनिक ID और लॉग जहाँ पठनीयता ज़रूरी |
v7/ULID में हॉट-स्पॉट सावधानी: यदि सारी लिखाइयाँ एक ही शार्ड/लीडर पर जाएँ तो लगातार जोड़ (append-heavy) वर्कलोड में B-Tree पत्तियाँ गर्म हो सकती हैं। प्रिफिक्स शफल या शार्ड की जोड़कर लोड फैलाएँ।
डेटाबेस कार्यान्वयन नोट्स (PostgreSQL / MySQL / SQLite)
- PostgreSQL
- v4/v7:
uuid
टाइप सर्वश्रेष्ठ। v7 को टेक्स्ट के रूप में लाएँ,uuid
में कास्ट करें, प्राकृतिक क्रम मिल जाता है। - ULID:
char(26)
/text
या Base32 रूपांतरण के बादbytea(16)
।
- v4/v7:
- MySQL / InnoDB
- v4/v7:
BINARY(16)
कॉम्पैक्ट और तेज़। v7 बिग-एंडियन रूप में समयक्रम सुरक्षित रखता है। ULIDCHAR(26)
या रूपांतरण के बादBINARY(16)
में।
- v4/v7:
- SQLite
- नेटिव UUID टाइप नहीं।
BLOB(16)
याTEXT
उपयोग करें। इंडेक्स्ड BLOB पर्याप्त प्रदर्शन देते हैं।
- नेटिव UUID टाइप नहीं।
सुरक्षा पर विचार
- अनुमान प्रतिरोध: v7/ULID में टाइमस्टैम्प बिट समान होते हैं। यदि एक ही मिलीसेकंड में ढेर ID बनाते हैं और रैंडमनेस कमजोर है, तो आस-पास के ID का अनुमान आसान हो जाता है। क्रिप्टोग्राफिक PRNG उपयोग करें और मोनोटोनिक समायोजन निष्पक्ष रखें।
- मेटाडेटा रिसाव: ID से निर्माण समय और अनुमानित निर्गमन मात्रा झलकती है। सार्वजनिक API में आंतरिक और बाहरी ID अलग रखने पर विचार करें।
सारांश: सही विकल्प कैसे चुनें
- UUID v4: पूर्ण रैंडम। कोई समयक्रम नहीं। सैद्धांतिक टकराव नगण्य। सेशन ID, CSRF टोकन जैसी आवश्यकताओं में उपयुक्त।
- UUID v7: क्रमबद्ध UUID। आंतरिक सिस्टम और डेटाबेस प्राइमरी की के लिए आदर्श। मोनोटोनिक जनरेशन से टकराव लगभग असंभव।
- ULID: अपेक्षाकृत मानव-अनुकूल। जब URL या लॉग में पठनीयता महत्त्वपूर्ण हो। आंतरिक प्राइमरी की में अक्सर v7 से कम सुविधाजनक। मोनोटोनिक जनरेशन से टकराव दूर रहता है।
परिशिष्ट: UUID v1 और v6 (संक्षेप में)
-
UUID v1 (समय-आधारित + MAC पता) 60-बिट टाइमस्टैम्प (100ns रिज़ॉल्यूशन) + नोड पहचानकर्ता (अक्सर MAC पता)। मजबूत समयक्रम देता है, पर MAC से होस्ट की जानकारी उजागर हो सकती है। क्लॉक रोलबैक संभालना पड़ता है, और निजता कारणों से आजकल कम पसंद किया जाता है।
-
UUID v6 (v1 का पुनर्संयोजन) v1 के टाइमस्टैम्प को बिग-एंडियन क्रम में पुनर्गठित करता है ताकि सॉर्टिंग सरल हो। इतिहास में इसे “sortable v1” कहा गया, पर मानकीकरण का रुझान अंततः v7 पर टिक गया। नई डिज़ाइन में v6 की जगह v7 अपनाना बेहतर।
कार्यान्वयन चेकलिस्ट
- रैंडमनेस के लिए क्रिप्टोग्राफिक सुरक्षित PRNG उपयोग करें।
- v7/ULID के मोनोटोनिक जनरेशन में पूर्वाग्रहपूर्ण रैंडमनेस से बचें जबकि एक ही मिलीसेकंड के टकराव रोकें।
- स्ट्रिंग कॉलम की कोलेशन लागत से बचने के लिए
uuid
/BINARY(16)
कॉलम को प्राथमिकता दें। - बाहरी ID नीति तय करें (क्या निर्गमन क्रम दिखाना स्वीकार्य है?). जरूरत पड़ने पर आंतरिक और बाहरी ID अलग रखें।
निचोड़: मौजूदा टूलिंग के साथ UUID v7 आंतरिक प्राइमरी की के लिए डिफ़ॉल्ट विकल्प है, जबकि ULID पठनीयता या विरासत सीमाओं वाले परिदृश्यों में उपयोगी है। जब टाइमस्टैम्प उजागर करना अस्वीकार्य हो तभी v4 या अन्य योजनाएँ चुनें।