2010-09-17 9 views
11

स्टोर करने के लिए सबसे अच्छी प्राथमिक कुंजी जो वेबसाइट पता और पेज यूआरएल स्टोर करने के लिए सबसे अच्छी प्राथमिक कुंजी है?यूआरएल

autoincremental id (जो वास्तव में डेटा से जुड़ा हुआ नहीं है) के उपयोग से बचने के लिए, मैंने प्राथमिक कुंजी के रूप में यूआरएल के SHA1 हस्ताक्षर के उपयोग के साथ स्कीमा तैयार किया।

यह दृष्टिकोण कई तरीकों से उपयोगी है: उदाहरण के लिए मुझे डेटाबेस से last_id पढ़ने की आवश्यकता नहीं है, इसलिए मैं कुंजी की गणना करने वाले सभी तालिका अपडेट तैयार कर सकता हूं और एक ही लेनदेन में वास्तविक अपडेट कर सकता हूं। कोई बाधा उल्लंघन नहीं।

वैसे भी मैंने दो किताबें पढ़ीं जो मुझे बताती हैं कि मैं गलत हूं। "उच्च प्रदर्शन MySQL" में यह कहा जाता है कि यादृच्छिक कुंजी डीबी अनुकूलक के लिए अच्छा नहीं है। इसके अलावा, प्रत्येक जो सेल्को की किताबों में वह कहता है कि प्राथमिक कुंजी डेटा का कुछ हिस्सा होना चाहिए।

सवाल यह है कि: यूआरएल के लिए प्राकृतिक कुंजी हैं ... स्वयं यूआरएल हैं। तथ्य यह है कि यदि किसी साइट के लिए यह छोटा है (www.something.com), तो यूआरएल के लिए लगाई गई सीमा नहीं है (http://www.boutell.com/newfaq/misc/urllength.html देखें)।

विचार करें कि मुझे उनमें से कुछ लाखों को स्टोर (और साथ काम करना) है।

तब सबसे अच्छी कुंजी कौन सा है? Autoincremental आईडी, यूआरएल, यूआरएल के हैंश?

+1

मुझे लगता है कि यह इन यूआरएल, एक्सेस के पैटर्न इत्यादि के साथ आप और क्या कर रहे हैं, इस पर निर्भर करने जा रहे हैं। SHA1 का उपयोग टकराव से सुरक्षित होना चाहिए, जहां एक छोटा हैश फ़ंक्शन (उदाहरण के लिए सीआरसी 32) स्पष्ट रूप से अनुचित होगा, लेकिन टकराव अभी भी संभव हो सकता है, आप बस दुर्भाग्यपूर्ण होगा। –

उत्तर

15

आप एक ऑटोइनक्रिकमेंट न्यूमेरिक प्राथमिक कुंजी चाहते हैं। उन समयों के लिए जब आपको आस-पास पास करने या अन्य तालिकाओं के खिलाफ शामिल होने की आवश्यकता होती है (उदाहरण के लिए, यूआरएल के लिए वैकल्पिक विशेषताओं), तो आप कुछ छोटे और संख्यात्मक चाहते हैं।

आप जो अन्य कॉलम और इंडेक्स चाहते हैं, उसके लिए यह हमेशा के रूप में निर्भर करता है कि आप उनका उपयोग कैसे करेंगे।

प्रत्येक यूआरएल के हैश को संग्रहीत करने वाला एक कॉलम लगभग किसी भी एप्लिकेशन के लिए एक उत्कृष्ट विचार है जो बड़ी संख्या में यूआरएल का उपयोग करता है। यह अपने पूर्ण पाठ द्वारा जितनी जल्दी हो सके उतना तेज़ यूआरएल चुनता है। दूसरा फायदा यह है कि यदि आप उस कॉलम को अद्वितीय बनाते हैं, तो आपको वास्तविक यूआरएल अद्वितीय कॉलम बनाने के बारे में चिंता करने की आवश्यकता नहीं है, और आप सरल, तेज़ परमाणु लेखन संचालन के रूप में रीप्लेस इंटो और इंसर्ट इग्नोर का उपयोग कर सकते हैं।

मैं जोड़ता हूं कि MySQL के अंतर्निहित MD5() फ़ंक्शन का उपयोग इस उद्देश्य के लिए ठीक है। इसका एकमात्र नुकसान यह है कि एक समर्पित हमलावर टकराव को मजबूर कर सकता है, जो मुझे पूरा यकीन है कि आपको परवाह नहीं है। अंतर्निर्मित फ़ंक्शन का उपयोग करना, उदाहरण के लिए, कुछ प्रकार के जुड़ना बहुत आसान होता है। तार के पूरे यूआरएल को पास करने के लिए यह थोड़ा सा धीमा हो सकता है ("जहां हैश = '32charhexstring'" के बजाय हैश = MD5 ('verylongurl') "यूआरएल से यूआरएल चुनें, लेकिन आपके पास विकल्प होगा ऐसा करने के लिए यदि आप चाहते हैं। जब तक आप एक ठोस परिदृश्य के साथ नहीं आ सकते हैं जहां MD5() आपको नीचे जाने देगा, इसका उपयोग करने में संकोच न करें।

कठिन सवाल यह है कि आपको अपने पूर्ण पाठ के अलावा अन्य तरीकों से यूआरएल देखने की आवश्यकता होगी: उदाहरण के लिए, क्या आप किसी भी "बार" से "/ foo" से शुरू होने वाले सभी यूआरएल खोजना चाहेंगे। कॉम "मेजबान? जबकि "पसंद"% bar.com%/foo% '"परीक्षण में काम करेगा, यह पैमाने पर खराब तरीके से विफल हो जाएगा। यदि आपकी ज़रूरतों में ऐसी चीजें शामिल हैं, तो आप आवश्यक डेटा के प्रकार पर लक्षित गैर-अद्वितीय सूचकांक उत्पन्न करने के रचनात्मक तरीकों के साथ आ सकते हैं ... शायद स्टार्टर्स के लिए डोमेन_नाम कॉलम। आपको अपने कॉलम से उन कॉलमों को पॉप्युलेट करना होगा, लगभग निश्चित रूप से (ट्रिगर्स और संग्रहीत प्रक्रियाएं यहां के लायक होने की तुलना में बहुत अधिक परेशानी होती हैं, खासकर यदि आप प्रदर्शन के बारे में चिंतित हैं - परेशान न करें)।

अच्छी खबर यह है कि संबंधपरक डेटाबेस उस तरह की चीज़ के लिए बहुत लचीले होते हैं। आप हमेशा नए कॉलम जोड़ सकते हैं और बाद में उन्हें पॉप्युलेट कर सकते हैं। मैं स्टार्टर्स के लिए सुझाव दूंगा: int unsigned auto_increment प्राथमिक कुंजी, अद्वितीय हैश चार (32), और (64K वर्ण पर्याप्त मानते हैं) टेक्स्ट यूआरएल।

+0

+1 - व्यापक प्राथमिक कुंजीपटल कुंजी पर होने वाले गंभीर प्रदर्शन प्रभाव हैं, जो SQL टीम द्वारा अच्छी तरह से प्रलेखित हैं और ज्यादातर डेवलपर्स द्वारा अनदेखा किए जाते हैं। – TomTom

+0

हैश को दशमलव रूप के बजाय हेक्स के रूप में क्यों स्टोर करना है? –

1

इस बात पर निर्भर करता है कि आप तालिका का उपयोग कैसे करते हैं। यदि आप अधिकतर WHERE url='<url>' के साथ चयन करते हैं, तो एक कॉलम तालिका होना ठीक है। यदि आप अपने ऐप के सभी स्थानों पर एक यूआरएल की पहचान करने के लिए एक ऑटोइनक्रिकमेंट आईडी का उपयोग कर सकते हैं, तो ऑटोइनक्रिएशन

2

संभवतः आप सीजीआई पैरामीटर और अन्य सामान समेत एक होस्टनाम नहीं बल्कि पूरे होस्ट के बारे में बात कर रहे हैं।

SHA-1 URL को हैश करना सभी चाबियाँ लंबे समय तक बनाता है, और परेशानी को हल करने में काफी अस्पष्ट बनाता है। मुझे दो टेबल में शामिल होने की क्षमता बनाए रखने के दौरान कुछ गोपनीय डेटा अस्पष्ट करने के लिए एक बार हैश पर इंडेक्स का उपयोग करना पड़ा, और प्रदर्शन खराब था।

दो संभावित दृष्टिकोण हैं। एक बेवकूफ और स्पष्ट है; यह वास्तव में mySQL में अच्छी तरह से काम करेगा। इसमें सादगी, और कुशलता से खोजने के लिए 'जो भी%' की तरह यूआरएल का उपयोग करने की क्षमता है।

लेकिन अगर आप कुछ डोमेन में केंद्रित यूआरएल ... उदाहरण के लिए के बहुत सारे ....

http://stackoverflow.com/questions/3735390/best-primary-key-for-storing-urls 
http://stackoverflow.com/questions/3735391/how-to-add-a-c-compiler-flag-to-extconf-rb 

आदि है, तो आप अनुक्रमित जो केवल अंतिम अक्षर में भिन्नता है पर देख रहे हैं। इस मामले में आप अपने चरित्र आदेश के साथ यूआरएल को संग्रहित और अनुक्रमणित करने पर विचार कर सकते हैं। यह एक अधिक कुशलता से उपयोग सूचकांक के लिए नेतृत्व कर सकते हैं।

(Oracle तालिका सर्वर उत्पाद होता है एक एक तथाकथित उलट सूचकांक के साथ ऐसा करने के रास्ते में निर्माण किया है।)

अगर मैं तुम्हें थे मैं एक autoincrement कुंजी जब तक आप दो से अधिक शामिल होने की आवश्यकता से बच जाएंगे टेबल ON TABLE_A.URL = TABLE_B.URL या उस तरह के मीटिंग के साथ कुछ अन्य शामिल स्थिति।

+1

हैश पर जुड़ने के लिए प्रदर्शन में सुधार करने का एक तरीका हैश डेटा के अधिक "केंद्रित" संस्करण के साथ एक दूसरा अनुक्रमित कॉलम जोड़ना है। एमडी 5 के पहले 64 बिट्स के साथ एक बिगिनट को CHAR (32) से अधिक कुशलता से अनुक्रमित किया जा सकता है। टकराव एक अरब गुना अधिक आम होगा, जो कहने के लिए, बेहद दुर्लभ है। आपका WHERE दोनों स्तंभों में शामिल हो सकता है ("जहां t1.inthash = t2.inthash और t1.charhash = t2.charhash") और बिगिन टकराव के बेहद दुर्लभ मामले में, पूर्ण हैश यह सुनिश्चित करेगा कि आपको अभी भी सही उत्तर मिल जाएगा। –