रिसोर्स की ID: GUID या Sequential?
(twitter.com/dylayed)किसी खास रिसोर्स को uniquely पहचानने वाली ID कैसे बनाई जाए, इस बारे में आम तौर पर दो बड़े तरीके ज़्यादा इस्तेमाल होते हैं। एक तरीका यह है कि DB table की Primary Key पर Auto Increment लगाकर मिलने वाले क्रमिक integer मान को ज्यों का त्यों इस्तेमाल किया जाए, और दूसरा तरीका यह है कि random 128-bit मान, यानी GUID (जिसे UUID भी कहते हैं), को हर बार generate करके इस्तेमाल किया जाए.
वेब पर दिखने वाली अनगिनत सेवाओं का डेटा बड़े पैमाने पर RDBMS संभालता है, और ऐसे DBMS का Auto Increment अंदरूनी रूप से काफ़ी optimized होता है। डेवलपर के नज़रिए से भी इसे समझना और predict करना आसान है, और डेटा को उसके आने के क्रम में sort करना भी सरल होता है। आखिर इसमें बस संख्या को 1-1 करके बढ़ाया ही जाता है। लेकिन इस तरीके में कुछ समस्याएँ भी हैं, जैसे कुछ मामलों में ऐसी जानकारी बाहर उजागर हो सकती है जिसे सुरक्षा कारणों से exposed नहीं होना चाहिए (उदाहरण के लिए कोई competitor हमारी service के user count जैसे मुख्य संकेतक आसानी से भाँप सकता है), या distributed architecture में यह समस्या पैदा कर सकता है.
GUID का इस्तेमाल करने का तरीका ऊपर के बिल्कुल उलट विशेषताएँ रखता है। GUID बिना किसी दूसरी dependency के हर बार ऐसा लगभग-unique 128-bit मान बनाता है जिसकी collision संभावना लगभग शून्य के करीब होती है। इसलिए distributed architecture में भी यह बिना किसी दिक्कत के काम करता है, और बाहर ऐसी कोई meaningful जानकारी अनजाने में लीक होने का खतरा भी नहीं रहता। लेकिन RDBMS में randomly generated मानों का उपयोग performance degradation ला सकता है, और अपने आप में यह डेटा को आने के क्रम में sort करना भी संभव नहीं बनाता। इन कमज़ोरियों को पूरा करने के लिए कभी-कभी पूरी तरह random की जगह time information मिलाकर आंशिक sequential गुण देने वाली चीज़ें, जैसे Timeflake, इस्तेमाल की जाती हैं। मैंने इसे खुद इस्तेमाल नहीं किया है, लेकिन सुना है कि Laravel जैसे framework भी इस तरह का तरीका अपनाते हैं।
व्यक्तिगत रूप से, मैं जिस कंपनी में अभी काम करता हूँ वहाँ Microsoft Office 365 या Graph API जैसे GUID का सक्रिय रूप से उपयोग करने वाले सिस्टमों के साथ integrate होने वाले प्रोडक्ट बना रहा हूँ, इसलिए मुझे यह सोचने का मौका मिला कि GUID को सक्रिय रूप से इस्तेमाल करने वाला तरीका भी काफ़ी अच्छा हो सकता है। लेकिन आखिरकार ऐसी चीज़ों में क्या बेहतर है, यह उपयोग-स्थिति और उद्देश्य पर निर्भर करता है, इसलिए हर तरीके के फायदे और नुकसान को साफ़ तौर पर समझकर रखना अच्छा है। इसी वजह से मैं इससे जुड़े एक काल्पनिक service developer की डायरी के रूप में लिखे गए tweet thread का परिचय दे रहा हूँ।
15 टिप्पणियां
हाल ही में Shinhan Card में धोखाधड़ी से उपयोग की एक घटना हुई, और इसके संबंध में यह जोखिम सामने आया कि संबंधित कार्ड कंपनी ने credit card नंबर क्रमवार जारी किए, जिसके कारण वे विदेश से होने वाले fraudulent use के प्रति उजागर हो सकते थे.
नंबर में बस थोड़ा बदलाव किया और "payment"… चोरी के जोखिम में उजागर credit card
Financial Supervisory Service, हाल की Shinhan Card धोखाधड़ी उपयोग आदि पर उपाय तैयार कर रहा है
कई लोगों ने टिप्पणियाँ कीं, जिसकी वजह से मुझे बहुत-सी ऐसी बातें भी पता चलीं जिन्हें मैं पहले अच्छी तरह नहीं जानता था.
इसी कारण मैंने पहली बार Hashids, Nano ID और Instagram के इस्तेमाल का तरीका जैसी चीज़ों के बारे में जाना.
प्रेरणा शायद ulid जैसी ही है, लेकिन एक प्रस्तावित Internet Draft मौजूद है, इसलिए मैंने यह spec अपने पिछले प्रोजेक्ट में इस्तेमाल किया था.
https://github.com/uuid6/uuid6-ietf-draft
इस तरह से बनने वाली id systems अक्सर दिखती हैं, लेकिन अब कम से कम UUID-like चीज़ों को तो एक ही मानक में एकजुट कर देने का समय आ गया है।
लेकिन बिखरे हुए standards को एक में एकीकृत करने के लिए नया standard बनाने की कोशिश अक्सर बाज़ार में बस एक नया competitor ही जोड़ देती है, ऐसा कहते हैं। हाहा
https://xkcd.com/927/
बिलकुल हाहा इसलिए शायद सब लोग नए id के सुझाव दे रहे हैं।
कुछ समय पहले Gyu-won जी ने यह साझा किया था, लेकिन क्या यह वास्तव में कोई जटिल समस्या नहीं है?
https://byterot.blogspot.com/2013/02/…
मुझे भी "simple problem" वाली बात के लिए अतिरिक्त स्पष्टीकरण चाहिए।
आप किस मायने में इसे एक सरल समस्या कह रहे हैं?
इस लेख में यह कहा गया है कि 'With storage nowadays very cheap, this normally is not a problem from the storage point of view.', लेकिन ऐसी स्थितियाँ भी होती हैं जहाँ यह id नेटवर्क पर घूमना पड़ता है, या मेमोरी में key की भूमिका निभानी पड़ती है, या यह बड़े पैमाने के डेटा में कई जगह इस्तेमाल होने वाली key होती है; ऐसे में कुछ bytes भी कम करना महत्वपूर्ण हो सकता है, इसलिए स्थिति के अनुसार UUID को अस्वीकार करना पड़ने वाली परिस्थितियाँ भी होती हैं।
इस लेख में जिस समस्या की बात की गई है, वह random तरीके से बनाए गए values को primary key के रूप में इस्तेमाल करने पर होने वाली performance गिरावट है
(अगर कोई दूसरी समस्या भी उल्लेखित की गई है और मैं उसे पकड़ नहीं पाया, तो कृपया बताइए)
उस समस्या का जवाब पहले से मौजूद है। यह वही समस्या है जो time order में cursor based pagination करते समय आती है, इसलिए लगता है कि आप में से ज़्यादातर लोग इसका समाधान पहले ही निकाल चुके होंगे।
किस मायने में यह एक जटिल समस्या है, यह जानने की जिज्ञासा मुझे भी है.
आपने कहा कि यह ऐसी स्थिति है जिसे अस्वीकार किया जाना चाहिए, तो यह एक सरल समस्या लगती है...
क्या जटिल समस्या वह नहीं होती, जब इस ओर या उस ओर कोई भी निर्णय नहीं लिया जा सके?
मैंने यह इसलिए पूछा क्योंकि 'सरल समस्या' कहने का अर्थ कई तरह से समझा जा सकता है, और मैं जानना चाहता था कि आपने यह किस अर्थ में कहा। जैसे, क्या आपका मतलब यह है कि समस्या खुद कठिन नहीं है, या फिर यह कि लेख में कोई स्पष्ट जवाब(?) दिया गया है, इसलिए उस पर ज्यादा सोचने की गुंजाइश नहीं है।
पहले वाले मामले में, जैसा ऊपर कहा गया है, परिस्थितियों के अनुसार कभी-कभी id को database के बाहर भी इस्तेमाल किया जाना पड़ सकता है, इसलिए विचार करने वाले कारक बढ़ जाते हैं और मुझे नहीं लगता कि यह कोई सरल समस्या है।
python/django में ऐसा भी है https://pypi.org/project/django-hashid-field/1.0.0/
ओह, Hashids जैसा एक तरीका भी है।
अगर Salt लीक हो जाए, तो ऊपर मूल लेख में जिन जानकारी के बाहरी रूप से उजागर होने की बात की गई थी, वैसी समस्या हो सकती है, लेकिन फिर भी मुझे लगता है कि यह एक अच्छा तरीका है.
ulid भी है। 128bit, समय क्रम में sort किया जा सकता है.
https://github.com/ulid/spec
काफी सारी चीज़ें एक-दूसरे जैसी दिखती हैं, तो शायद इंसानी सोच भी ज़्यादातर वहीं की वहीं होती है…?