2011-07-08 11 views
6

मैं आरएफसी 4122 के सेक्शन 4.4 (http://www.ietf.org/rfc/rfc4122.txt) में वर्णित वी 4 यूयूआईडी उत्पन्न करने के लिए एक MySQL संग्रहीत फ़ंक्शन लिखने का प्रयास कर रहा हूं।मैं अपने MySQL UUID v4 संग्रहीत फ़ंक्शन को कैसे बढ़ा सकता हूं?

CREATE FUNCTION UUID_V4() 
RETURNS BINARY(16) 
READS SQL DATA 
BEGIN 
    SET @uuid = CONCAT(
     LPAD(HEX(FLOOR(RAND() * 4294967296)), 8, '0'), 
     LPAD(HEX(FLOOR(RAND() * 4294967296)), 8, '0'), 
     LPAD(HEX(FLOOR(RAND() * 4294967296)), 8, '0'), 
     LPAD(HEX(FLOOR(RAND() * 4294967296)), 8, '0') 
    ); 
    SET @uuid = CONCAT(
     SUBSTR(@uuid FROM 1 FOR 12), 
     '4', 
     SUBSTR(@uuid FROM 14 FOR 3), 
     SUBSTR('ab89' FROM FLOOR(1 + RAND() * 4) FOR 1), 
     SUBSTR(@uuid FROM 18) 
    ); 
    RETURN UNHEX(@uuid); 
END 

ऊपर समारोह है काफी धीमी गति से: लगभग 100 बार में निर्मित UUID() की तुलना में धीमी, MySQL के BENCHMARK() सुविधा के अनुसार कुछ बदलाव के बाद मेरे प्रारंभिक अनुभवहीन प्रयास पीछा कर रहा है। MySQL के सी एपीआई का उपयोग करके एक यूडीएफ लिखने के लिए, क्या कोई सुधार है जो मैं यहां अपने रनटाइम से परिमाण के क्रम को दाढ़ी देने के लिए कह सकता हूं?

यदि पहले से मौजूद, अच्छी तरह से सम्मानित यूयूआईडी यूडीएफ या संग्रहीत प्रक्रिया है, तो मुझे इसके बारे में भी सुनकर खुशी होगी।

+0

मुझे जवाब नहीं पता है, लेकिन आप पहले से ही उल्लिखित MySQL के UUID() एक का उपयोग करने के बजाय अपना स्वयं का फ़ंक्शन कैसे बनाना चाहते हैं (मुझे नहीं पता कि MySQL का आरएफसी 4122 से अलग है, तो अगर यह क्षमा करें पूछने के लिए)? –

+0

MySQL का 'UUID() 'RFC4122 के अनुसार यूयूआईडी उत्पन्न नहीं करता है, और जिस तरह से यह उत्पन्न करता है, यह कथन-आधारित प्रतिकृति को तोड़ देता है। –

+2

आपका फ़ंक्शन स्टेटमेंट-आधारित प्रतिकृति भी तोड़ देगा। आप बिनलॉग प्रारूप को "मिश्रित" या "ROW" पर सेट करके इससे बच सकते हैं, इसलिए लॉग का पुनरावृत्ति फ़ंक्शन को कॉल नहीं करेगा, लेकिन वास्तविक पंक्ति मान डालें जो यूयूआईडी() को उपयोग के लिए व्यवहार्य बनाता है। साथ ही, क्या गारंटी है कि आपका फ़ंक्शन डुप्लिकेट यूयूआईडी उत्पन्न नहीं करेगा? आपको मिला एकमात्र यादृच्छिक कारक रैंड() के लिए 5 कॉल है (जो इसे पहले स्थान पर धीमा कर देता है)। मैं MySQL के लिए एक यूडीएफ लिखूंगा और फ़ंक्शन के माध्यम से समाधान बनाने के बजाय इसे इस तरह कार्यान्वित करूंगा, जिससे बेहतर प्रदर्शन बेहतर हो सके। –

उत्तर

9

मैंने इसे सहीता या प्रदर्शन के लिए परीक्षण नहीं किया। यह केवल दो के बजाय एकमात्र concatenation करने का विचार है।

create function uuid_v4() 
returns binary(16) 
begin 
    set @h1 = lpad(hex(floor(rand() * 4294967296)), 8, '0'); 
    set @h2 = lpad(hex(floor(rand() * 4294967296)), 8, '0'); 
    set @h3 = lpad(hex(floor(rand() * 4294967296)), 8, '0'); 
    set @h4 = lpad(hex(floor(rand() * 4294967296)), 8, '0'); 

    set @uuid = concat(
     @h1, 
     substr(@h2 from 1 for 4), 
     '4', 
     substr(@h2 from 6), 
     substr('ab89' from floor(1 + rand() * 4) for 1), 
     substr(@h3 from 2), 
     @h4 
    ); 
    return unhex(@uuid); 
end 
; 

इसके अलावा आप अपने कार्य में READS SQL DATA का उपयोग क्यों करते हैं?

+0

फिर से 'एसक्यूएल डेटा पढ़ता है': मुझे वर्तमान में कथन-आधारित प्रतिकृति का उपयोग करना है, और 'डिटर्मिनेस्टिक', 'नहीं एसक्यूएल', या 'एसडीएस डेटा पढ़ना' इसे तोड़ने के लिए जरूरी नहीं है। –

+0

लेकिन आप जानते हैं कि यह कथन दोहराने के लिए सुरक्षित नहीं है, है ना? – TehShrike

संबंधित मुद्दे