UUID बनाम ULID बनाम serial IDs: जानें कि प्रत्येक ID इंडेक्सिंग, सॉर्टिंग, शार्डिंग और प्रोजेक्ट्स में सुरक्षित एक्सपोर्ट/इम्पोर्ट को कैसे प्रभावित करता है।

पहले हफ्ते में ID चुनना उबाऊ लगता है। फिर आप शिप करते हैं, डेटा बढ़ता है, और वह "सरल" निर्णय हर जगह दिखने लगता है: इंडेक्स, URLs, लॉग्स, एक्सपोर्ट और इंटीग्रेशन।
असल सवाल यह नहीं है कि "कौन सा सबसे अच्छा है?" बल्कि यह है "कौन सा दर्द आप बाद में टालना चाहते हैं?" IDs बदलना मुश्किल है क्योंकि वे दूसरे टेबल्स में कॉपी हो जाते हैं, क्लाइंट्स द्वारा कैश किए जाते हैं, और अन्य सिस्टम्स उन पर निर्भर हो जाते हैं।
जब ID उत्पाद के विकास से मेल नहीं खाती, तो आप आमतौर पर इसे कुछ जगहों पर देखते हैं:
हमेशा अब की सुविधा और बाद की फ्लेक्सिबिलिटी के बीच ट्रेडऑफ़ रहता है। Serial integers पढ़ने में आसान और अक्सर तेज़ होते हैं, पर वे रिकॉर्ड काउंट लीक कर सकते हैं और डेटा मर्ज करना मुश्किल बना सकते हैं। रैंडम UUIDs सिस्टम्स के बीच यूनिकनेस के लिए बेहतरीन हैं, पर इंडेक्स पर प्रभाव और लोगन पढ़ने में कठिनाई जैसे नुक़सान होते हैं। ULIDs वैश्विक यूनिकनेस और टाइम-रुचि क्रम दोनों देने की कोशिश करते हैं, पर इनके भी स्टोरेज और टूलिंग ट्रेडऑफ़ होते हैं।
एक उपयोगी तरीका सोचने का: यह ID किसके लिए है?
अगर ID मुख्य रूप से इंसानों (सपोर्ट, डीबग, ऑप्स) के लिए है, तो छोटा और स्कैन करने योग्य जीतता है। अगर यह मशीनों के लिए है (डिस्ट्रिब्यूटेड राइट्स, ऑफ़लाइन क्लाइंट्स, मल्टी-रीजन सिस्टम), तो ग्लोबल यूनिकनेस और कोलिज़न अवॉइडेंस ज्यादा मायने रखती है।
लोग जब कहते हैं "UUID vs ULID vs serial IDs," तो वे असल में चुन रहे होते हैं कि हर रो को एक यूनिक लेबल कैसे दिया जाए। वह लेबल बाद में इन्सर्ट, सॉर्ट, मर्ज और मूव करने की आसानी को प्रभावित करता है।
एक serial ID एक काउंटर है। डेटाबेस 1 देता है, फिर 2, फिर 3, और ऐसे आगे (आम तौर पर integer या bigint में स्टोर)। यह पढ़ने में आसान, स्टोरेज में सस्ता और अक्सर तेज़ होता है क्योंकि नई पंक्तियाँ इंडेक्स के अंत में आती हैं।
एक UUID 128-bit पहचानकर्ता है जो रैंडम दिखता है, जैसे 3f8a.... अधिकांश सेटअप में इसे डेटाबेस से अगला नंबर पूछे बिना जेनरेट किया जा सकता है, इसलिए अलग-अलग सिस्टम स्वतंत्र रूप से IDs बना सकते हैं। इसका ट्रेडऑफ़ यह है कि रैंडम-लुकिंग इन्सर्ट्स इंडेक्स को ज्यादा मेहनत कराते हैं और साधारण bigint से अधिक जगह लेते हैं।
ULID भी 128-bit है, पर इसे प्रायः टाइम-ऑर्डर के अनुसार डिजाइन किया गया है। नए ULIDs आम तौर पर पुराने के बाद सॉर्ट होते हैं, जबकि वे ग्लोबली यूनिक भी रहते हैं। आप UUID की "कहीं से भी जेनरेट" सुविधा के कुछ फायदे समय-अनुरूप व्यवहार के साथ पाते हैं।
संक्षेप में:
Serial IDs एकल-डेटाबेस ऐप्स और आंतरिक टूल्स में सामान्य हैं। UUIDs तब आते हैं जब डेटा कई सेवाओं, डिवाइसों या रीजन में बनता है। ULIDs उन टीमों में लोकप्रिय हैं जो डिस्ट्रिब्यूटेड ID जेनरेशन चाहती हैं पर सॉर्ट ऑर्डर, पेजिनेशन या "नए पहले" क्वेरीज़ की परवाह भी करती हैं।
एक प्राइमरी की आम तौर पर इंडेक्स (आमतौर पर B-tree) द्वारा बैक की जाती है। उस इंडेक्स को एक सॉर्ट किए हुए फोन बुक की तरह सोचिए: हर नई पंक्ति को सही स्थान पर जोड़ने की ज़रूरत होती है ताकि लुकअप तेज़ रहें।
रैंडम IDs (क्लासिक UUIDv4) के साथ नई एंट्रीज़ इंडेक्स में हर जगह उतरती हैं। इसका मतलब है कि डेटाबेस कई इंडेक्स पेज छूता है, पेज स्प्लिट्स अधिक होते हैं, और अतिरिक्त लिखाई होती है। समय के साथ इंडेक्स चर्न बढ़ता है: हर इन्सर्ट पर अधिक काम, अधिक कैश मिस और अपेक्षा से बड़े इंडेक्स।
लगभग बढ़ने वाले IDs (serial/bigint, या समय-ऑर्डर्ड IDs जैसे कई ULIDs) के साथ डेटाबेस आमतौर पर नई एंट्रीज़ को इंडेक्स के अंत के पास जोड़ सकता है। यह कैश-फ्रेंडली होता है क्योंकि हाल के पेज गर्म रहते हैं, और उच्च राइट रेट पर इन्सर्ट सामान्यतः स्मूद रहते हैं।
की साइज मायने रखती है क्योंकि इंडेक्स एंट्रीज़ मुफ्त नहीं हैं:
बड़े कीज़ का मतलब है कि हर इंडेक्स पेज पर कम एंट्रीज़ फिट होती हैं। इससे गहरे इंडेक्स, क्वेरी पर अधिक पेज पढ़ने और तेज़ रहने के लिए ज्यादा RAM की ज़रूरत होती है।
अगर आपकी एक "events" तालिका है जिसमें लगातार इन्सर्ट्स होते हैं, तो एक रैंडम UUID प्राइमरी की एक bigint की तुलना में जल्दी धीमा लगने लगेगा, भले ही सिंगल-रो लुकअप अभी भी ठीक लगें। यदि आप भारी राइट की उम्मीद करते हैं, तो इंडेक्सिंग कॉस्ट आमतौर पर पहला असली फर्क होता है जो आप नोटिस करते हैं।
अगर आपने "Load more" या इनफिनिटी स्क्रॉल बनाया है, तो आपने पहले ही उन IDs की पेन देखी होगी जो अच्छी तरह सॉर्ट नहीं करते। एक ID "अच्छे से सॉर्ट" करती है जब उस पर ऑर्डर करने पर आपको एक स्थिर, मायने रखने वाला ऑर्डर (अक्सर क्रिएशन टाइम) मिलता है ताकि पेजिनेशन प्रेडिक्टेबल रहे।
रैंडम IDs (जैसे UUIDv4) के साथ, नई पंक्तियाँ बिखरी होती हैं। id द्वारा ऑर्डर करना समय से मेल नहीं खाता, और कर्सर पेजिनेशन जैसे "मुझे इस id के बाद की आइटम दे दो" भरोसेमंद नहीं रहते। आप आमतौर पर created_at पर वापिस जाते हैं, जो ठीक है, पर इसे सावधानी से करना होता है।
ULIDs को लगभग समय-ऑर्डर के लिए डिज़ाइन किया गया है। यदि आप ULID के अनुसार सॉर्ट करते हैं (स्ट्रिंग या बाइनरी रूप में), तो नए आइटम आमतौर पर बाद में आते हैं। इससे कर्सर पेजिनेशन सरल हो जाती है क्योंकि कर्सर अंतिम देखी गई ULID हो सकती है।
ULID फीड्स के लिए प्राकृतिक समय-सीधापन, सरल कर्सर और UUIDv4 की तुलना में कम रैंडम इन्सर्ट दर्द देता है।
पर ULID परफेक्ट समय-क्रम की गारंटी नहीं देता—खासकर जब एक ही मिलीसेकंड में कई मशीनों पर IDs जेनरेट हों। यदि आपको सटीक ऑर्डर चाहिए तो आपको अभी भी एक वास्तविक टाइमस्टैम्प चाहिए।
created_at बेहतर हैजब आप बैकफिल कर रहे हों, ऐतिहासिक रिकॉर्ड इम्पोर्ट कर रहे हों, या स्पष्ट टाई-ब्रेकिंग चाहिए, तो created_at अक्सर सुरक्षित होता है।
एक व्यावहारिक पैटर्न है कि आप (created_at, id) से ऑर्डर करें, जहाँ id सिर्फ टाई-ब्रेक के लिए हो।
शार्डिंग का मतलब है एक डेटाबेस को कई छोटे डेटाबेसेज़ में बाँटना ताकि हर शार्ड डेटा का हिस्सा रखें। टीमें आमतौर पर यह बाद में करती हैं, जब एक सिंगल डेटाबेस स्केल करने में मुश्किल लगे या यह सिंगल पॉइंट ऑफ़ फेलियर बन जाए।
आपका ID चुनाव शार्डिंग को आसान या दर्दनाक बना सकता है।
सीक्वेंशियल IDs (auto-increment serial या bigint) के साथ हर शार्ड खुशी-खुशी 1, 2, 3... जेनरेट करेगा। वही ID कई शार्ड्स पर मौजूद हो सकती है। पहली बार जब आपको डेटा मर्ज करना हो, रो मूव करनी हों, या क्रॉस-शार्ड फीचर्स बनानी हों, तब टकराव दिखाई देते हैं।
आप समन्वय के साथ टकराव से बच सकते हैं (एक सेंट्रल ID सर्विस, या शार्ड्स के लिए रेंज), पर यह मूविंग पार्ट्स जोड़ता है और एक बॉटलनेक बन सकता है।
UUIDs और ULIDs समन्वय कम करते हैं क्योंकि हर शार्ड स्वतंत्र रूप से IDs जेनरेट कर सकता है और डुप्लिकेट्स का जोखिम बेहद कम रहता है। यदि आप कभी भी डेटा को कई डेटाबेस में विभाजित करने का सोचते हैं, तो यह शुद्ध सीक्वेंस के खिलाफ सबसे मजबूत तर्कों में से एक है।
एक सामान्य समझौता है शार्ड प्रिफिक्स जोड़ना और फिर हर शार्ड पर लोकल सीक्वेंस का उपयोग करना। आप इसे दो कॉलम में स्टोर कर सकते हैं, या एक वैल्यू में पैक कर सकते हैं।
यह काम करता है, पर यह एक कस्टम ID फॉर्मेट बनाता है। हर इंटीग्रेशन को इसे समझना पड़ेगा, सॉर्टिंग बिना एक्स्ट्रा लॉजिक के वैश्विक टाइम ऑर्डर नहीं देगी, और शार्ड्स के बीच डेटा मूव करने पर IDs को री-राइट करना पड़ सकता है (जो रेफरेंसेज़ को तोड़ देता है यदि वे शेयर किए गए हों)।
एक जल्दी प्रश्न पूछें: क्या आपको कभी कई डेटाबेसेज़ से डेटा मिलाकर रेफरेंस स्थिर रखना होगा? अगर हाँ, तो पहले दिन से ग्लोबली यूनिक IDs की योजना बनाएं, या बाद में माइग्रेशन के लिए बजट रखें।
एक्सपोर्ट/इम्पोर्ट वह जगह है जहाँ ID चुनाव सैद्धांतिक से व्यावहारिक बनता है। जिस पल आप prod से staging क्लोन करते हैं, बैकअप रिस्टोर करते हैं, या दो सिस्टम्स से डेटा मर्ज करते हैं, आप देखेंगे कि आपकी IDs कितनी पोर्टेबल और स्थिर हैं।
Serial (auto-increment) IDs के साथ आप आमतौर पर सुरक्षित रूप से दूसरी DB में इन्सर्ट्स को रीप्ले नहीं कर सकते और उम्मीद कर सकते हैं कि रेफ़रेंसेज़ बरकरार रहें जब तक आप मूल नंबरों को संरक्षित न रखें। अगर आप सिर्फ कुछ रो इम्पोर्ट कर रहे हैं (मान लीजिए 200 कस्टमर्स और उनके ऑर्डर), तो आपको टेबल्स को सही क्रम में लोड करना होगा और वही प्राइमरी कीज़ रखनी होंगी। अगर कुछ फिर से नंबर हो जाए तो फॉरेन कीज़ टूट जाएँगी।
UUIDs और ULIDs डेटाबेस सीक्वेंस के बाहर जेनरेट होते हैं, इसलिए इन्हें एनवायरनमेंट्स के बीच मूव करना आसान होता है। आप रो को कॉपी कर सकते हैं, IDs को रख सकते हैं, और रिलेशनशिप्स सही रहेंगी। इससे बैकअप रिस्टोर, पार्टियल एक्सपोर्ट या मर्ज में मदद मिलती है।
उदाहरण: प्रोडक्शन से 50 अकाउंट्स एक्सपोर्ट करके स्टेजिंग में एक बग डिबग करना। UUID/ULID प्राइमरी कीज़ के साथ आप उन अकाउंट्स और संबंधित रो (प्रोजेक्ट्स, इनवॉइस, लॉग्स) इम्पोर्ट कर सकते हैं और सब कुछ सही पैरेंट को पॉइंट करेगा। सीरियल IDs के साथ अक्सर आप एक ट्रांसलेशन टेबल (old_id -> new_id) बनाते हुए फॉरेन कीज़ को इम्पोर्ट के दौरान री-राइट करते हैं।
बुल्क इम्पोर्ट्स के लिए, ID टाइप से अधिक बेसिक्स मायने रखते हैं:
यदि आप जल्दी से फैसला करना चाहते हैं तो उन चीज़ों पर ध्यान दें जो बाद में आपको चोट पहुंचाएँगी।
created_at पर सॉर्ट करना ठीक समझते हैं तो UUIDs और serial दोनों काम करते हैं।BIGINT आमतौर पर B-tree इंडेक्स पर सबसे आसान रहता है। रैंडम UUIDs अधिक चर्न पैदा करते हैं।सबसे बड़ी गलती यह है कि किसी ID को इसलिए चुन लेना क्योंकि वह लोकप्रिय है, और बाद में पता चलना कि वह आपके क्वेरी, स्केल या डेटा शेयरिंग के साथ टकराता है। अधिकतर समस्याएँ महीनों बाद दिखती हैं।
सामान्य असफलताएँ:
123, 124, 125 उपयोग करते हैं तो लोग नज़दीकी रिकॉर्ड्स अनुमान लगा सकते हैं और सिस्टम को स्कैन कर सकते हैं।सावधानी के संकेत जो जल्दी संबोधित करने चाहिए:
अधिकांश तालिकाओं में एक प्राइमरी की प्रकार चुनें और उस पर टिके रहें। प्रकार मिक्स करना (एक जगह bigint, दूसरी जगह UUID) जोइन, API और माइग्रेशन को कठिन बनाता है।
अपेक्षित पैमाने पर इंडेक्स साइज़ का अनुमान लगाएं। चौड़े कीज़ का मतलब बड़ा प्राइमरी इंडेक्स और ज्यादा मेमोरी/IO।
निर्धार करतीए कि आप कैसे पेजिनेट करेंगे। अगर आप ID से पेजिनेट करते हैं तो सुनिश्चित करें कि ID का ऑर्डर प्रेडिक्टेबल हो (या इसे न होने दें)। अगर आप टाइमस्टैम्प से पेजिनेट करते हैं तो created_at को इंडेक्स करें और उसे लगातार उपयोग करें।
उत्पादन-जैसे डेटा पर अपना इम्पोर्ट प्लान टेस्ट करें। सत्यापित करें कि आप रिकॉर्ड्स को फिर से बना सकते हैं बिना फॉरेन कीज़ तोड़े और कि री-इम्पोर्ट्स चुपचाप नए IDs नहीं जेनरेट करते।
अपनी कोलिज़न रणनीति लिखें। कौन ID जेनरेट करता है (DB या ऐप), और अगर दो सिस्टम ऑफ़लाइन रिकॉर्ड बनाते हैं और बाद में सिंक करते हैं तो क्या होगा?
सुनिश्चित करें कि सार्वजनिक URLs और लॉग्स वे पैटर्न न लीक करें जिनकी आपको परवाह है (रिकॉर्ड काउंट, क्रिएशन रेट, आंतरिक शार्ड हिंट)। अगर आप serial IDs उपयोग करते हैं तो मान लीजिए कि लोग नज़दीकी IDs अनुमान लगा सकते हैं।
एक सोलो फाउंडर एक सरल CRM लॉन्च करता है: contacts, deals, notes। एक Postgres डेटाबेस, एक वेब ऐप, और मुख्य लक्ष्य शिप करना है।
शुरुआत में, एक serial bigint प्राइमरी की परफेक्ट लगती है। इन्सर्ट तेज़ हैं, इंडेक्स साफ़ रहते हैं, और लॉग्स में पढ़ना आसान है।
एक साल बाद, एक कस्टमर ऑडिट के लिए क्वार्टरली एक्सपोर्ट चाहता है, और फाउंडर मार्केटिंग टूल से लीड्स इम्पोर्ट करने लगता है। जो IDs पहले सिर्फ आंतरिक थे, अब CSV फ़ाइलों, ईमेल और सपोर्ट टिकट्स में दिखने लगते हैं। अगर दो सिस्टम दोनों 1, 2, 3... उपयोग करते हैं, तो मर्जेस गंदे हो जाते हैं। आप स्रोत कॉलम, मैपिंग टेबल्स या इम्पोर्ट के दौरान IDs को फिर से लिखने लगते हैं।
दूसरे साल तक मोबाइल ऐप आ जाता है। उसे ऑफ़लाइन रहते हुए रिकॉर्ड बनाना होगा और बाद में सिंक करना होगा। अब आपको ऐसे IDs चाहिए जो क्लाइंट पर बिना डेटाबेस से बात किए बन सकें और अलग-अलग एनवायरनमेंट्स में आने पर कम टकराव रखें।
एक समझौता जो अक्सर अच्छा चलता है:
अगर आप UUID, ULID और serial IDs के बीच फंसे हुए हैं, तो अपने डेटा के मूव और ग्रोथ के आधार पर तय करें।
एक-वाक्य विकल्प सामान्य मामलों के लिए:
bigint serial प्राइमरी की उपयोग करें।मिश्रण अक्सर सबसे अच्छा उत्तर होता है। आंतरिक तालिकाओं (जॉइन टेबल्स, बैकग्राउंड जॉब्स) के लिए serial bigint रखें, और यूज़र्स, ऑर्ग्स, इनवॉइस जैसी सार्वजनिक एंटिटीज़ के लिए UUID/ULID रखें जिन्हें आप एक्सपोर्ट, सिंक या किसी अन्य सर्विस से रेफर कर सकते हैं।
यदि आप Koder.ai (koder.ai) पर बना रहे हैं, तो बहुत सारी तालिकाएँ और APIs जेनरेट करने से पहले अपने ID पैटर्न का निर्णय लेना फायदेमंद होता है। प्लेटफ़ॉर्म का प्लानिंग मोड और स्नैपशॉट/रोलबैक स्कीमा बदलते समय जल्दी व सुरक्षित वेरिफ़िकेशन में मदद करते हैं।
भविष्य में आपको किस तरह का दर्द नहीं उठाना है—यह तय करके शुरू करें: रैंडम इंडेक्स राइट्स से धीमे इन्सर्ट, अजीब पेजिनेशन, जोखिम भरे माइग्रेशन, या इम्पोर्ट/मर्ज के दौरान ID टकराव। अगर आप मानते हैं कि डेटा कई सिस्टमों के बीच चलेगा या कई जगह बनेंगे, तो डिफ़ॉल्ट रूप से ग्लोबली यूनिक ID (UUID/ULID) चुनें और टाइम-ऑर्डरिंग की चिंताओं को अलग रखें।
Serial bigint तब अच्छा विकल्प है जब आपका एक ही डेटाबेस है, राइट्स भारी हैं और IDs आंतरिक रहते हैं। यह कॉम्पैक्ट है, B-tree इंडेक्स पर तेज़ है और लॉग्स में पढ़ने में आसान है। मुख्य कमज़ोरी यह है कि भविष्य में डेटा मर्ज करने पर टकराव आते हैं और यह सार्वजनिक रूप से एक्सपोज़ होने पर रिकॉर्ड काउंट लीक कर सकता है।
UUIDs चुनें जब रिकॉर्ड कई सर्विसेज़, रीजन, डिवाइस या ऑफ़लाइन क्लाइंट्स में बन सकते हैं और आप बिना समन्वय के बहुत कम टकराव जोखिम चाहते हैं। UUIDs सार्वजनिक-facing IDs के रूप में भी अच्छे हैं क्योंकि उन्हें अनुमान लगाना मुश्किल होता है। ट्रेडऑफ़ बड़े इंडेक्स और सुसंगत क्रमहीन इन्सर्ट पैटर्न हैं, जो सेक्वेन्शल कीज़ की तुलना में अधिक ओवरहेड ला सकते हैं।
ULIDs उन हालातों में बेहतर हैं जहाँ आप चाहें कि IDs कहीं से भी बन सकें और आम तौर पर क्रिएशन टाइम के अनुसार सॉर्ट भी हों। इससे कर्सर पेजिनेशन सरल होता है और UUIDv4 जैसी रैंडम-इन्सर्ट की समस्या घटती है। हालाँकि ULID को सटीक टाइमस्टैम्प मत समझिए—यदि सटीक ऑर्डर चाहिए तो created_at रखें।
हाँ, खासकर UUIDv4-शैली की रैंडमनेस वाले केस में लिखने-भरे तालिकाओं पर असर पड़ता है। रैंडम इन्सर्ट्स प्राइमरी की इंडेक्स को फैलाते हैं, पेज स्प्लिट्स और कैश चर्न बढ़ाते हैं, और समय के साथ इंडेक्स बड़े व धीमे हो सकते हैं। आप अक्सर इसे पहले स्थायी रूप से धीमे इन्सर्ट रेट और बड़े मेमोरी/IO की जरूरत के रूप में नोटिस करेंगे, न कि सरल एक-रो लुकअप की धीमी गति के रूप में।
क्योंकि UUIDv4 जैसे रैंडम IDs क्रिएशन टाइम के अनुरूप नहीं होते, id द्वारा ऑर्डर करना समय के क्रम से मेल नहीं खाता—इसलिए “इस id के बाद के आइटम दे दो” जैसे कर्सर स्थिर टाइमलाइन नहीं देंगे। भरोसेमंद समाधान है कि created_at से पेजिनेट करें और tie-breaker के तौर पर id जोड़ें, जैसे (created_at, id)। अगर आप सिर्फ ID पर पेजिनेट करना चाहते हैं तो टाइम-सॉर्टेबल ID जैसे ULID सरल विकल्प हैं।
सीरियल IDs शार्ड्स में टकराते हैं क्योंकि हर शार्ड स्वतंत्र रूप से 1, 2, 3... जेनरेट करेगा। टकराव से बचने के लिए समन्वय जरूरी होता है (शार्ड-रेंज या सेंट्रल ID सर्विस), जो ऑपरेशनल जटिलता और बॉटलनेक बना सकता है। UUIDs/ULIDs इस समन्वय की ज़रूरत कम करते हैं क्योंकि हर शार्ड स्वतंत्र रूप से सुरक्षित IDs जेनरेट कर सकता है।
UUIDs/ULIDs सुरक्षित रहते हैं क्योंकि आप रो को एक्सपोर्ट करके कहीं और इम्पोर्ट कर सकते हैं और रेफरेंसेज़ बरकरार रहते हैं। Serial IDs के साथ आंशिक इम्पोर्ट करने पर अक्सर एक ट्रांसलेशन टेबल (old_id -> new_id) बनानी और फॉरेन कीज़ फिर से लिखनी पड़ती है, जो आसानी से ग़लत हो सकती है। यदि आप अक्सर एनवायरनमेंट क्लोन या मर्ज करते हैं, तो ग्लोबल-यूनिक IDs समय बचाते हैं।
अकसर दो IDs रखना अच्छा पैटर्न है: एक कॉम्पैक्ट आंतरिक प्राइमरी की (serial bigint) जो जॉइन और स्टोरेज के लिए प्रभावी हो, और एक अपरिवर्तनीय पब्लिक ID (ULID या UUID) जो URLs, APIs, एक्सपोर्ट्स और क्रॉस-सिस्टम रेफरेंसेज़ के लिए हो। यह डेटाबेस को तेज़ रखता है और इंटीग्रेशन/माइग्रेशन को आसान बनाता है—बस पब्लिक ID को स्थिर मानें और उसे रीसायकल न करें।
जल्दी में तय करें और कॉन्सिस्टेंट रहें। Koder.ai में अपनी डिफ़ॉल्ट ID स्ट्रैटेजी प्लानिंग मोड में पहले तय करें, बहुत सारा स्कीमा व एंडपॉइंट जनरेट करने से पहले, और स्नैपशॉट/रोलबैक का उपयोग करके छोटे आकार पर स्कीमा बदलाव वैलिडेट करें। सबसे कठिन हिस्सा नए IDs बनाना नहीं होता—बल्कि फॉरेन कीज़, कैशेज़, लॉग्स और बाहरी पेलोड जो पुराने IDs को रेफर करते रहते हैं, वो होते हैं।