guid - मुझे GUS को MySQL तालिकाओं में कैसे स्टोर करना चाहिए?




uuid (9)

क्या मैं वर्कर (36) का उपयोग करता हूं या ऐसा करने के लिए कोई बेहतर तरीका है?


Answers

GUID स्ट्रिंग में टाइमस्टैम्प के बिट लेआउट के लिए KCD द्वारा पोस्ट की गई GuidToBinary दिनचर्या को ध्यान में रखा जाना चाहिए। यदि स्ट्रिंग एक संस्करण 1 यूयूआईडी का प्रतिनिधित्व करती है, जैसे यूयूआईडी () mysql रूटीन द्वारा लौटाए गए लोगों की तरह, तो टाइम घटक घटक 1-जी में एम्बेडेड होते हैं, डी को छोड़कर।

12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
12345678 = least significant 4 bytes of the timestamp in big endian order
9ABC     = middle 2 timestamp bytes in big endian
D        = 1 to signify a version 1 UUID
EFG      = most significant 12 bits of the timestamp in big endian

जब आप बाइनरी में कनवर्ट करते हैं, तो अनुक्रमण के लिए सबसे अच्छा क्रम होगा: EFG9ABC12345678D + बाकी।

आप 12345678 को 78563412 पर स्वैप नहीं करना चाहते हैं क्योंकि बड़े एंडियन पहले से ही सर्वश्रेष्ठ बाइनरी इंडेक्स बाइट ऑर्डर प्राप्त करते हैं। हालांकि, आप चाहते हैं कि सबसे महत्वपूर्ण बाइट निचले बाइट्स के सामने चले जाएं। इसलिए, ईएफजी पहले जाते हैं, इसके बाद मध्यम बिट्स और निचले बिट्स होते हैं। एक मिनट के दौरान uuid () के साथ एक दर्जन या तो यूयूआईडी उत्पन्न करें और आपको देखना चाहिए कि यह क्रम सही रैंक कैसे उत्पन्न करता है।

select uuid(), 0
union 
select uuid(), sleep(.001)
union 
select uuid(), sleep(.010)
union 
select uuid(), sleep(.100)
union 
select uuid(), sleep(1)
union 
select uuid(), sleep(10)
union
select uuid(), 0;

/* output */
6eec5eb6-9755-11e4-b981-feb7b39d48d6
6eec5f10-9755-11e4-b981-feb7b39d48d6
6eec8ddc-9755-11e4-b981-feb7b39d48d6
6eee30d0-9755-11e4-b981-feb7b39d48d6
6efda038-9755-11e4-b981-feb7b39d48d6
6f9641bf-9755-11e4-b981-feb7b39d48d6
758c3e3e-9755-11e4-b981-feb7b39d48d6 

पहले दो यूयूआईडी समय के साथ निकटतम उत्पन्न हुए थे। वे केवल पहले ब्लॉक के अंतिम 3 निबल्स में भिन्न होते हैं। ये टाइमस्टैम्प के कम से कम महत्वपूर्ण बिट्स हैं, जिसका अर्थ है कि हम उन्हें दाईं ओर धक्का देना चाहते हैं जब हम इसे एक अनुक्रमणीय बाइट सरणी में परिवर्तित करते हैं। काउंटर उदाहरण के रूप में, अंतिम आईडी सबसे वर्तमान है, लेकिन केसीडी के स्वैपिंग एल्गोरिदम इसे तीसरे आईडी (डीसी से पहले 3 डी, पहले ब्लॉक से अंतिम बाइट्स) से पहले रखेगा।

अनुक्रमण के लिए सही क्रम होगा:

1e497556eec5eb6... 
1e497556eec5f10... 
1e497556eec8ddc... 
1e497556eee30d0... 
1e497556efda038... 
1e497556f9641bf... 
1e49755758c3e3e... 

सहायक जानकारी के लिए यह आलेख देखें: http://mysql.rjweb.org/doc.php/uuid

*** ध्यान दें कि मैं टाइमस्टैम्प के उच्च 12 बिट्स से संस्करण निबल को विभाजित नहीं करता हूं। यह आपके उदाहरण से डी निबल है। मैं बस इसे सामने फेंक देता हूँ। तो मेरा बाइनरी अनुक्रम डीईएफजी 9एबीसी और इसी तरह से समाप्त होता है। इसका तात्पर्य है कि मेरे सभी अनुक्रमित यूयूआईडी एक ही नींबू से शुरू होते हैं। लेख एक ही बात करता है।


उन लोगों के लिए जो सिर्फ इस पर ठोकर खा रहे हैं, अब परकोना द्वारा शोध के अनुसार एक बेहतर विकल्प है।

इसमें इष्टतम अनुक्रमण के लिए यूयूआईडी भाग को पुनर्गठित करना शामिल है, फिर कम भंडारण के लिए बाइनरी में परिवर्तित करना शामिल है।

here पूरा लेख पढ़ें


ThaBadDawg द्वारा उत्तर में जोड़ने के लिए, 36 लंबाई स्ट्रिंग से वापस 16 की बाइट सरणी में प्राप्त करने के लिए इन आसान कार्यों (मेरा एक बुद्धिमान कॉलेग्यू के लिए धन्यवाद) का उपयोग करें।

DELIMITER $$

CREATE FUNCTION `GuidToBinary`(
    $Data VARCHAR(36)
) RETURNS binary(16)
DETERMINISTIC
NO SQL
BEGIN
    DECLARE $Result BINARY(16) DEFAULT NULL;
    IF $Data IS NOT NULL THEN
        SET $Data = REPLACE($Data,'-','');
        SET $Result =
            CONCAT( UNHEX(SUBSTRING($Data,7,2)), UNHEX(SUBSTRING($Data,5,2)),
                    UNHEX(SUBSTRING($Data,3,2)), UNHEX(SUBSTRING($Data,1,2)),
                    UNHEX(SUBSTRING($Data,11,2)),UNHEX(SUBSTRING($Data,9,2)),
                    UNHEX(SUBSTRING($Data,15,2)),UNHEX(SUBSTRING($Data,13,2)),
                    UNHEX(SUBSTRING($Data,17,16)));
    END IF;
    RETURN $Result;
END

$$

CREATE FUNCTION `ToGuid`(
    $Data BINARY(16)
) RETURNS char(36) CHARSET utf8
DETERMINISTIC
NO SQL
BEGIN
    DECLARE $Result CHAR(36) DEFAULT NULL;
    IF $Data IS NOT NULL THEN
        SET $Result =
            CONCAT(
                HEX(SUBSTRING($Data,4,1)), HEX(SUBSTRING($Data,3,1)),
                HEX(SUBSTRING($Data,2,1)), HEX(SUBSTRING($Data,1,1)), '-', 
                HEX(SUBSTRING($Data,6,1)), HEX(SUBSTRING($Data,5,1)), '-',
                HEX(SUBSTRING($Data,8,1)), HEX(SUBSTRING($Data,7,1)), '-',
                HEX(SUBSTRING($Data,9,2)), '-', HEX(SUBSTRING($Data,11,6)));
    END IF;
    RETURN $Result;
END
$$

CHAR(16) वास्तव में एक BINARY(16) , अपना पसंदीदा स्वाद चुनें

कोड को बेहतर तरीके से पालन करने के लिए, नीचे दिए गए अंकों का आदेश दिया गया GUID दिया गया उदाहरण लें। (अवैध पात्रों का उपयोग चित्रकारी उद्देश्यों के लिए किया जाता है - प्रत्येक स्थान एक अद्वितीय चरित्र होता है।) कार्य बेहतर इंडेक्स क्लस्टरिंग के लिए थोड़ा ऑर्डर प्राप्त करने के लिए बाइट ऑर्डरिंग को बदल देगा। Reordered guid उदाहरण के नीचे दिखाया गया है।

12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
78563412-BC9A-FGDE-HIJK-LMNOPQRSTUVW

डैश हटा दिए गए:

123456789ABCDEFGHIJKLMNOPQRSTUVW
78563412BC9AFGDEHIJKLMNOPQRSTUVW

"बेहतर" उस पर निर्भर करता है जिसके लिए आप अनुकूलित कर रहे हैं।

स्टोरेज आकार / प्रदर्शन बनाम विकास की आसानी के बारे में आप कितना ख्याल रखते हैं? सबसे महत्वपूर्ण बात यह है कि क्या आप पर्याप्त GUID उत्पन्न कर रहे हैं, या उन्हें अक्सर पर्याप्त रूप से ला रहे हैं, यह महत्वपूर्ण है?

अगर उत्तर "नहीं" है, तो char(36) पर्याप्त से अधिक है, और यह GUID को मृत-सरल संग्रहित / लाता है। अन्यथा, binary(16) उचित है, लेकिन आपको सामान्य स्ट्रिंग प्रस्तुति से पीछे और आगे कनवर्ट करने के लिए MySQL और / या अपनी प्रोग्रामिंग भाषा पसंद पर निर्भर होना होगा।


मेरे डीबीए ने मुझसे पूछा कि जब मैंने अपनी वस्तुओं के लिए GUID को स्टोर करने का सबसे अच्छा तरीका पूछा, तो मुझे 16 बाइट्स स्टोर करने की आवश्यकता क्यों थी जब मैं एक ही चीज को 4 बाइट्स में एक इंटीजर के साथ कर सकता था। चूंकि उसने मुझे उस चुनौती को मेरे पास रखा था, इसलिए मैंने सोचा कि अब इसका उल्लेख करने का अच्छा समय था। ऐसा कहे जाने के बाद...

यदि आप स्टोरेज स्पेस का सबसे इष्टतम उपयोग करना चाहते हैं तो आप एक GUID को CHAR (16) बाइनरी के रूप में स्टोर कर सकते हैं।


मैं नीचे दिए गए कार्यों का उपयोग करने का सुझाव दूंगा क्योंकि @ bigh_29 द्वारा उल्लिखित लोगों ने मेरे guids को नए रूप में बदल दिया है (उन कारणों से जिन्हें मैं समझ नहीं पा रहा हूं)। इसके अलावा, मेरे टेबल पर किए गए परीक्षणों में ये थोड़ा तेज़ हैं। https://gist.github.com/damienb/159151

DELIMITER |

CREATE FUNCTION uuid_from_bin(b BINARY(16))
RETURNS CHAR(36) DETERMINISTIC
BEGIN
  DECLARE hex CHAR(32);
  SET hex = HEX(b);
  RETURN LOWER(CONCAT(LEFT(hex, 8), '-', MID(hex, 9,4), '-', MID(hex, 13,4), '-', MID(hex, 17,4), '-', RIGHT(hex, 12)));
END
|

CREATE FUNCTION uuid_to_bin(s CHAR(36))
RETURNS BINARY(16) DETERMINISTIC
RETURN UNHEX(CONCAT(LEFT(s, 8), MID(s, 10, 4), MID(s, 15, 4), MID(s, 20, 4), RIGHT(s, 12)))
|

DELIMITER ;

मैं इसे एक char (36) के रूप में स्टोर करूंगा।


यदि आपके पास मानक GUID के रूप में स्वरूपित एक char / varchar मान है, तो आप इसे आसानी से CONCAT + SUBSTR के उन सभी दिमाग-दबाने वाले अनुक्रमों के बिना सरल CAST (MyString AS BINARY16) का उपयोग करके BINARY (16) के रूप में स्टोर कर सकते हैं।

बिनरी (16) फ़ील्ड की तुलना स्ट्रिंग की तुलना में बहुत तेज़ / क्रमबद्ध / अनुक्रमित की जाती है, और डेटाबेस में दो गुना कम स्थान लेती है


सरल जवाब है: कोई फर्क नहीं पड़ता , वे एक ही बात हैं। उन्हें 16 बाइट (128 बिट्स) मान के रूप में देखें जो एक अद्वितीय मूल्य के रूप में उपयोग किया जाता है। माइक्रोसॉफ्ट में बोलते हैं उन्हें GUID कहा जाता है, लेकिन माइक्रोसॉफ्ट-स्पीच का उपयोग नहीं करते समय उन्हें यूयूआईडी कहते हैं।

यहां तक ​​कि यूयूआईडी विनिर्देश के लेखक और माइक्रोसॉफ्ट का दावा है कि वे समानार्थी हैं:

  • आईईटीएफ आरएफसी 4122 के परिचय से " एक सार्वभौमिक अद्वितीय पहचानकर्ता (यूयूआईडी) यूआरएन नेमस्पेस ": "यूआईआईडीएस (सार्वभौमिक अद्वितीय पहचानकर्ता) के लिए एक समान संसाधन नाम नामस्थान, जिसे GUIDs (वैश्विक रूप से अद्वितीय पहचानकर्ता) के रूप में भी जाना जाता है।"

  • आईटीयू-टी सिफारिश X.667 से, आईएसओ / आईईसी 9834-8: 2004 अंतर्राष्ट्रीय मानक : " यूयूआईडी को विश्व स्तर पर अद्वितीय पहचानकर्ता (GUIDs) के रूप में भी जाना जाता है, लेकिन इस शब्द का उपयोग इस सिफारिश में नहीं किया जाता है।"

  • और माइक्रोसॉफ्ट का claims है कि यूयूआईडी आरएफसी द्वारा एक GUID निर्दिष्ट किया गया है: "माइक्रोसॉफ्ट विंडोज प्रोग्रामिंग और विंडोज ऑपरेटिंग सिस्टम में, एक वैश्विक रूप से अद्वितीय पहचानकर्ता (GUID), जैसा कि [आरएफसी 4122] में निर्दिष्ट है, शब्द है ... शब्द सार्वभौमिक अद्वितीय पहचानकर्ता (यूयूआईडी ) कभी-कभी विंडोज प्रोटोकॉल विनिर्देशों में GUID के समानार्थी के रूप में प्रयोग किया जाता है। "

लेकिन सही उत्तर इस बात पर निर्भर करता है कि प्रश्न "यूयूआईडी" कहता है ...

पहला भाग इस बात पर निर्भर करता है कि पूछताछकर्ता क्या सोच रहा है जब वे "यूयूआईडी" कह रहे हैं।

माइक्रोसॉफ्ट के दावे का तात्पर्य है कि सभी यूयूआईडी GUID हैं। लेकिन सभी GUID असली यूयूआईडी हैं? यही है, सभी यूयूआईडी का सेट सिर्फ सभी GUID के सेट का उचित सबसेट है, या यह एक ही सटीक सेट है?

आरएफसी 4122 के विवरण को देखते हुए, यूयूआईडी के चार अलग-अलग "वेरिएंट" हैं। यह ज्यादातर इसलिए है क्योंकि ऐसे 16 बाइट पहचानकर्ता यूयूआईडी विनिर्देश के निर्माण में उन विनिर्देशों को एक साथ लाए जाने से पहले उपयोग में थे। आरएफसी 4122 की धारा 4.1.1 से, यूयूआईडी के चार प्रकार हैं:

  1. आरक्षित, नेटवर्क कंप्यूटिंग सिस्टम पिछड़ा संगतता
  2. आरएफसी 4122 में निर्दिष्ट संस्करण (जिसमें से पांच उप-वेरिएंट हैं, जिन्हें "संस्करण" कहा जाता है)
  3. आरक्षित, माइक्रोसॉफ्ट निगम पिछड़ा संगतता
  4. भविष्य की परिभाषा के लिए आरक्षित।

आरएफसी 4122 के मुताबिक, सभी यूयूआईडी वेरिएंट "असली यूयूआईडी" हैं, फिर सभी जीयूआईडी असली यूयूआईडी हैं। शाब्दिक प्रश्न के लिए "क्या GUID और UUID के बीच कोई अंतर है" जवाब निश्चित रूप से आरएफसी 4122 यूयूआईडी के लिए नहीं है : कोई फर्क नहीं पड़ता (लेकिन नीचे दूसरे भाग के अधीन)।

लेकिन सभी GUID वेरिएंट 2 यूयूआईडी नहीं हैं (उदाहरण के लिए माइक्रोसॉफ्ट COM में GUIDs हैं जो संस्करण 3 यूयूआईडी हैं)। यदि सवाल था "क्या GUID और संस्करण 2 यूयूआईडी के बीच कोई अंतर है", तो उत्तर हाँ होगा - वे अलग-अलग हो सकते हैं। प्रश्न पूछने वाले किसी को शायद वेरिएंट के बारे में पता नहीं है और वे केवल "यूयूआईडी" शब्द कह सकते हैं (उदाहरण के लिए वे एमएसी एड्रेस + समय और यादृच्छिक संख्या एल्गोरिदम फॉर्म यूयूआईडी के बारे में जानते हैं, जो वे केवल 2 यूयूआईडी के बारे में सोच रहे हैं। संस्करण 2 के दोनों संस्करण हैं)। इस मामले में, जवाब हाँ अलग है

तो जवाब, कुछ हद तक, इस बात पर निर्भर करता है कि जब व्यक्ति "यूयूआईडी" शब्द कहता है तो वह क्या सोच रहा है। क्या उनका मतलब वेरिएंट 2 यूयूआईडी है (क्योंकि यह एकमात्र संस्करण है जिसे वे जानते हैं) या सभी यूयूआईडी?

दूसरा भाग यूयूआईडी की परिभाषा के रूप में उपयोग किए जाने वाले विनिर्देशों पर निर्भर करता है।

यदि आपको लगता है कि यह भ्रमित था, तो आईटीयू-टी एक्स 667 आईएसओ / आईईसी 9834-8: 2004 पढ़ें जिसे आरएफसी 4122 के साथ गठबंधन और पूरी तरह से तकनीकी रूप से संगत माना जाना चाहिए। क्लॉज 11.2 में इसकी एक अतिरिक्त वाक्य है, जो कहती है, "सभी यूयूआईडी इस सिफारिश के अनुरूप हैं। अंतर्राष्ट्रीय मानक में ऑक्टेट 7 के सेट 7 के बिट 7 और ऑक्टेट 7 सेट 0 के बिट 6 के साथ भिन्न बिट्स होंगे। जिसका अर्थ है कि केवल संस्करण 2 यूयूआईडी उस मानक के अनुरूप है (उन दो बिट मानों का अर्थ भिन्नता 2 है)। यदि यह सत्य है, तो सभी GUID आईटीयू-टी / आईएसओ / आईईसी यूयूआईडी का पालन नहीं कर रहे हैं, क्योंकि अनुरूप आईटीयू-टी / आईएसओ / आईईसी यूयूआईडी केवल वैरिएंट 2 मान हो सकते हैं।

इसलिए, वास्तविक उत्तर यह भी निर्भर करता है कि यूयूआईडी के किस विनिर्देश के बारे में पूछ रहा है। मान लीजिए कि हम सभी यूयूआईडी के बारे में स्पष्ट रूप से बात कर रहे हैं न कि सिर्फ 2 यूयूआईडीएस: जीआईआईडी और आईईटीएफ के यूयूआईडी के बीच कोई अंतर नहीं है , लेकिन जीयूआईडी के बीच हां अंतर और आईटीयू-टी / आईएसओ / आईईसी के यूयूआईडी के अनुरूप है !

बाइनरी एन्कोडिंग भिन्न हो सकती है

बाइनरी में एन्कोड किए जाने पर (मानव-पठनीय पाठ प्रारूप के विपरीत), GUID en.wikipedia.org/wiki/Globally_unique_identifier संरचना के रूप में चार अलग-अलग क्षेत्रों के साथ en.wikipedia.org/wiki/Globally_unique_identifier किया en.wikipedia.org/wiki/Globally_unique_identifier है। यह प्रारूप केवल पहले 3 फ़ील्ड के बाइट ऑर्डर में यूयूआईडी मानक से अलग है।

Bits  Bytes Name   Endianness  Endianness
                   (GUID)      RFC 4122

32    4     Data1  Native      Big
16    2     Data2  Native      Big
16    2     Data3  Native      Big
64    8     Data4  Big         Big




mysql guid uuid