दिलचस्प पोस्ट
PHP लॉगिन सिस्टम: मुझे याद रखें (लगातार कुकी) Pickle.dump – TypeError का प्रयोग करना: स्ट्रेट होना चाहिए, बाइट्स नहीं स्विफ्ट – NSViewController से keydown कब्जा जावा में एक नई सूची कैसे बनाएं पैरामॉरफीम्स क्या हैं? सर्वश्रेष्ठ प्रदर्शन के साथ सर्वलेट प्रतिक्रिया के लिए चित्र लेखन आईफोन सिम्युलेटर कहां स्टोर करता है? कैसे mysql में levenshtein समारोह जोड़ने के लिए? उद्देश्य-सी / सी में संख्या / फ्लोट के बाद "f" MySQL में एक संचयी राशि कॉलम बनाएँ प्रोग्रामेटिक रूप से संबंधित लेआउट में एक दूसरे के नीचे देखें JQuery के उपयोग से मैं एक तालिका की एक पंक्ति को कैसे देख सकता हूँ (element.scrollintoView)? JSON युक्ति – कुंजी को उद्धरण चिह्नों से घिरा होना चाहिए? एक XElement के InnerXml प्राप्त करने का सबसे अच्छा तरीका है? कैसे एक्सेल VBA चर एकाधिक मैक्रोज़ के लिए उपलब्ध बनाने के लिए?

मैं MySQL तालिकाओं में GUID कैसे संग्रहीत करूँ?

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

वेब के समाधान से एकत्रित समाधान "मैं MySQL तालिकाओं में GUID कैसे संग्रहीत करूँ?"

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

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

मैं उसे एक चारार (36) के रूप में संग्रहीत करता हूं

थाबडदौग के जवाब में जोड़ना, 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 को दिए उदाहरण दें। (गैरकानूनी पात्रों को दृष्टांत के उद्देश्यों के लिए उपयोग किया जाता है – प्रत्येक जगह एक अद्वितीय चरित्र।) कार्य बेहतर सूचकांक क्लस्टरिंग के लिए बिट ऑर्डर प्राप्त करने के लिए बाइट क्रम को बदल देगा। पुनः निर्देशित गइड उदाहरण के नीचे दिखाया गया है।

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

डैश हटाए गए:

 123456789ABCDEFGHIJKLMNOPQRSTUVW 78563412BC9AFGDEHIJKLMNOPQRSTUVW 

चार (36) एक अच्छा विकल्प होगा इसके अलावा MySQL के यूयूआईडी () फ़ंक्शन का उपयोग किया जा सकता है जो 36-वर्णों का पाठ स्वरूप (हेक्स के साथ हेक्स) को रिटर्न करता है जिसे डीबी से ऐसे आईडी के पुनर्प्राप्ति के लिए इस्तेमाल किया जा सकता है।

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

आप भंडारण आकार / प्रदर्शन बनाम विकास के बारे में कितना परवाह करते हैं? इससे भी महत्वपूर्ण बात – क्या आप पर्याप्त GUIDs पैदा कर रहे हैं, या उन्हें पर्याप्त रूप से आकर्षित कर रहे हैं, यह महत्वपूर्ण है?

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

बाइनरी (16) बेहतर होगा, varchar (32) के उपयोग से बेहतर होगा

जीसीआईडी ​​स्ट्रिंग में टाइमस्टैम्प के बिट लेआउट के लिए किडीसीडी द्वारा पोस्ट किया गया GuidToBinary दिनचर्या को खाते में छू लिया जाना चाहिए। अगर स्ट्रिंग एक संस्करण 1 UUID का प्रतिनिधित्व करता है, जैसे यूयूआईडी () mysql रूटीन द्वारा लौटाए जाते हैं, तो समय घटकों डी 1 को छोड़कर, 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 स्वैप नहीं करना चाहते क्योंकि बड़े एंडियन पहले से ही सबसे अच्छा बाइनरी इंडेक्स बाइट ऑर्डर देते हैं। हालांकि, आप चाहते हैं कि सबसे महत्वपूर्ण बाइट कम बाइट्स के सामने चले गए। इसलिए, ईएफजी पहले जाते हैं, इसके बाद मध्यम बिट्स और निचले बिट्स होते हैं। एक मिनट के दौरान यूयूआईडी (यूयूआईडी) के साथ दर्जन या तो यूआईआईडी उत्पन्न करें और आपको यह देखना चाहिए कि यह ऑर्डर सही रैंक कैसे पैदा करता है।

 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 एबीसी और इतने पर समाप्त होता है। इसका अर्थ है कि मेरे सभी अनुक्रमित यूयूआईडी एक ही चोंच के साथ शुरू होते हैं। लेख एक ही बात करता है

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

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

यहां पूरा लेख पढ़ें

मैं नीचे दिए गए कार्य का उपयोग करने का सुझाव दूंगा क्योंकि @ बीग_2 9 द्वारा उल्लिखित लोगों ने मेरे ग्रिड्स को नए में बदल दिया है (कारणों से मुझे समझ में नहीं आ रहा है)। इसके अलावा, ये मेरे टेबल्स पर किए गए परीक्षणों में थोड़े तेज़ हैं I 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 ; 

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

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