SQL डेटाबेस में प्राथमिक कुंजी के रूप में स्ट्रिंग्स


178

मैं डेटाबेस और सिद्धांतों के साथ बहुत परिचित नहीं हूं कि वे कैसे काम करते हैं। पूर्णांक की तुलना में प्राथमिक कुंजी के लिए स्ट्रिंग्स का उपयोग करने के लिए क्या यह एक प्रदर्शन के दृष्टिकोण (डालने / अद्यतन / क्वेरी) से धीमा है?

जवाबों:


191

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


11
यह डेटाबेस पर निर्भर नहीं करेगा? मुझे लगता है कि ठीक से अनुक्रमित स्ट्रिंग एक संख्या से बिल्कुल धीमी नहीं होगी?
रयान गुइल

2
मैं मानूंगा कि विचार करने के लिए बहुत सारे चर हैं। (Sqlserver में) हमने वास्तविक प्रदर्शन के मुद्दों को उच्च किशोरावस्था के बीच की लंबाई के साथ तार का उपयोग करते हुए और ऊपर भी अनुक्रमित होने पर देखा है। खरीदें आप सही हैं उदाहरण के लिए इस हार्डवेयर पर काबू पाने के लिए चीजें हैं।
kemiller2002

1
काफी उचित। मैं इस बात से सहमत हूँ कि यदि कोई स्ट्रिंग समझ में आता है, तो आपको इसका उपयोग करना चाहिए। मैं यह भी कहूंगा कि डेटाबेस में GUID या UUID फ़ील्ड्स के लिए निश्चित रूप से समय है जहाँ एक स्वत: अंकन फ़ील्ड काम नहीं करेगा।
रयान गुइल

7
यह भी ध्यान रखें कि सूचकांक तुलना करते समय अक्सर एक CHAR और VARCHAR के बीच बहुत बड़ा अंतर होता है
टॉम एच

7
इस उत्तर की टिप्पणियों की संख्या यह स्पष्ट करती है कि यह कितना अधूरा है। उल्लेख अनुक्रमण न्यूनतम स्वीकार्य उत्तर होता।
पेड्रो रोलो

74

स्ट्रिंग्स को एक प्राथमिक कुंजी के रूप में उपयोग करने के साथ एक और मुद्दा यह है कि क्योंकि सूचकांक को लगातार अनुक्रमिक क्रम में रखा जाता है, जब एक नई कुंजी बनाई जाती है जो उस क्रम के बीच में होती है जिसे सूचकांक को फिर से तैयार करना होता है ... यदि आप एक ऑटो का उपयोग करते हैं संख्या पूर्णांक, नई कुंजी बस सूचकांक के अंत में जोड़ा जाता है।


2
यह नए आवेषण के लिए "हॉट स्पॉट" का कारण बन सकता है। जब तक आप अपने डेटाबेस को ठीक से प्रबंधित कर रहे हैं, तब तक आपके पास आवेषण के लिए आपके पृष्ठों पर अतिरिक्त स्थान होना चाहिए और पृष्ठ विभाजन दुर्लभ होना चाहिए।
टॉम एच

20
यह तब होता है जब प्राथमिक कुंजियों को क्लस्टर किया जाता है। आप उन्हें अस्पष्ट भी बना सकते हैं।
सीखना

XID का आदेश दिया जाता है, जो अगर आप बस xid स्ट्रिंग्स का उपयोग करने में मदद कर सकते हैं
सिनास्टैटिक

22

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


अच्छे खर्च। लेकिन सभी SQL डेटाबेस के लिए यह सही है? मैंने प्राथमिक कुंजी के रूप में यादृच्छिक UUID का उपयोग करते समय MySQL के प्रदर्शन के मुद्दों के बारे में सुना है।
होजेबेल

13

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

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


26
स्ट्रिंग्स जो PK के लिए अच्छे उम्मीदवार हैं, उनके पास डुप्लिकेट नहीं हैं - अन्यथा वे PK के लिए अच्छे उम्मीदवार नहीं होंगे। ICD-9 कोड, देश कोड, VIN # के बारे में सोचें। प्राकृतिक कुंजियों के साथ एक समस्या के उदाहरण के रूप में एक नाम का उपयोग करना गलत है, क्योंकि उन्हें पहली बार में उम्मीदवार नहीं होना चाहिए।
टॉम एच

6
@ टॉम H: आईएसओ काउंटी कोड बदल जाते हैं। [ en.wikipedia.org/wiki/ISO_3166-1#Editions_and_changes ] संबंधित प्रश्न पर एक उत्तर के रूप में [ stackoverflow.com/questions/925266/… ] "
PRIM

4
@SteveSchnepp: हाँ और आईएसओ उस परिवर्तन के प्रबंधन के लिए विश्वसनीय निकाय है। दूसरी ओर, जब आपको किसी और के साथ पूर्णांक मूल्यों को बढ़ाने के अपने मोनोटोनिक अनुक्रम को मर्ज करने की आवश्यकता होती है, तो आप अपने दम पर हैं;)
onedaywhen

1
मैं इस बात से सहमत हूं कि नाम को एक कुंजी के रूप में नहीं माना जाता है, मैंने अभी-अभी ओमनी समय देखा है जब वे थे।
HLGEM

1
@onedaywhen विलय के पूर्णांक के 2 मोनोटोनिक अनुक्रम को आसानी से उपसर्ग या प्रत्यय के माध्यम से किया जाता है :)
स्टीव श्नाइप

6

इससे कोई फर्क नहीं पड़ता कि आप एक प्राथमिक कुंजी के रूप में इतने लंबे समय के लिए क्या उपयोग करते हैं। यदि आप गति या अच्छे डेटाबेस डिजाइन के बारे में परवाह करते हैं, तो जब तक आप डेटा को दोहराने की योजना नहीं बनाते हैं, तब GUID का उपयोग करें।

यदि यह एक एक्सेस डेटाबेस या कुछ छोटे ऐप है तो वास्तव में कौन परवाह करता है। मुझे लगता है कि इसका कारण यह है कि हम में से अधिकांश डेवलपर्स पुराने इंट या थप्पड़ को थप्पड़ मारते हैं क्योंकि परियोजनाएं हमारे ऊपर बढ़ने का एक तरीका है, और आप अपने आप को बढ़ने का विकल्प छोड़ना चाहते हैं।


5

बहुत अधिक चर। यह तालिका के आकार, सूचकांक, स्ट्रिंग कुंजी डोमेन की प्रकृति पर निर्भर करता है ...

आम तौर पर , पूर्णांक तेजी से होंगे। लेकिन क्या देखभाल करने के लिए अंतर काफी बड़ा होगा? य़ह कहना कठिन है।

इसके अलावा, स्ट्रिंग्स चुनने के लिए आपकी प्रेरणा क्या है? न्यूमेरिक ऑटो-इन्क्रीमेंट कीज अक्सर इतनी आसान भी होती हैं। क्या यह शब्दार्थ है? सुविधा? प्रतिकृति / काट दिया चिंताओं? यहां आपका जवाब आपके विकल्पों को सीमित कर सकता है। यह एक तीसरा "हाइब्रिड" विकल्प भी आपको याद कर रहा है जो आप भूल रहे हैं।


इसका कोई मतलब नहीं है, तुम क्या मतलब है?
एचएलजीईएम

@ एचएलजीईएम: अगर मैं उसे लिखने के लिए समझता हूं, तो उसका मतलब मुख्य डीबी के साथ लैपटॉप पर बनाए गए रिकॉर्ड को सिंक्रनाइज़ करना है।
जोएल कोएहॉर्न

मेरा मतलब है कि मेरे पास एक ही संस्थाओं के साथ दो अलग-अलग डेटाबेस हैं, केवल एक निरंतर भंडारण उद्देश्यों के लिए कम बार अद्यतन किया जाता है। अगर मैं डेटाबेस A पर इकाई "कैलिफ़ोर्निया" के लिए क्वेरी करता हूं, तो मैं चाहता हूं कि यह मौलिक रूप से डेटाबेस बी पर "कैलिफ़ोर्निया" समान हो
मेनस्ट्रीमरग्स

1
और यह एक लैपटॉप में बनाए गए रिकॉर्ड को 'जैसे' है कि यह एक ही समस्या है: एक स्थान पर बनाए गए रिकॉर्ड को दूसरे में बनाए गए रिकॉर्ड के साथ संघर्ष नहीं करना चाहिए। यहां एक संभावित समाधान है गाइड कीज।
जोएल कोएहॉर्न

5

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

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

क्या डेटा प्रविष्टि लोग या स्वचालित डेटा स्रोत हमेशा माना जाने वाला प्राकृतिक कुंजी के लिए एक मूल्य प्रदान करते हैं, या कभी-कभी छोड़ा जाता है? क्या यह इनपुट डेटा में कभी-कभी गलत है? यदि हां, तो त्रुटियों का पता कैसे लगाया जाता है और कैसे सही किया जाता है?

क्या प्रोग्रामर और इंटरएक्टिव उपयोगकर्ता हैं जो प्रश्नों को निर्दिष्ट करते हैं जो प्राकृतिक कुंजी का उपयोग करने में सक्षम हैं जो वे चाहते हैं?

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


3

सूचकांक बहुत सारी तुलना करते हैं।

आमतौर पर, तार पूर्णांक से अधिक होते हैं और तुलना के लिए टकराव के नियम लागू किए जा सकते हैं, इसलिए तार की तुलना आमतौर पर पूर्णांक की तुलना में अधिक कम्प्यूटेशनल रूप से गहन कार्य है।

कभी-कभी, हालांकि, यह एक string to numerical idमेज के साथ अतिरिक्त जुड़ने की तुलना में एक प्राथमिक कुंजी के रूप में एक स्ट्रिंग का उपयोग करने के लिए तेज़ है ।


2

हां, लेकिन जब तक आप लाखों पंक्तियों की अपेक्षा नहीं करते, स्ट्रिंग-आधारित कुंजी का उपयोग नहीं करते क्योंकि यह धीमी है आमतौर पर "समय से पहले अनुकूलन।" आखिरकार, स्ट्रिंग्स को बड़ी संख्याओं के रूप में संग्रहीत किया जाता है जबकि संख्यात्मक कुंजियों को आमतौर पर छोटी संख्याओं के रूप में संग्रहीत किया जाता है।

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


2

PK स्तंभों के लिए पूर्णांक का उपयोग करने के दो कारण:

  1. हम पूर्णांक फ़ील्ड के लिए पहचान सेट कर सकते हैं जो स्वचालित रूप से बढ़ा हुआ है।

  2. जब हम PKs बनाते हैं, तो db एक इंडेक्स (क्लस्टर या नॉन क्लस्टर) बनाता है जो तालिका में संग्रहीत होने से पहले डेटा को सॉर्ट करता है। PK पर पहचान का उपयोग करके, ऑप्टिमाइज़र को रिकॉर्ड सहेजने से पहले सॉर्ट क्रम की जाँच करने की आवश्यकता नहीं है। यह बड़े तालिकाओं पर प्रदर्शन में सुधार करता है।


1

एक प्राथमिक कुंजी के रूप में एक स्ट्रिंग होने का आपका कारण क्या है?

मैं बस एक ऑटो इंक्रीमेंटिंग पूर्णांक फ़ील्ड में प्राथमिक कुंजी सेट करूंगा, और स्ट्रिंग फ़ील्ड पर एक इंडेक्स डालूंगा।

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

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


3
मुझे लगता है कि किसी भी खुफिया को एक कुंजी में रखना मुसीबत के लिए पूछ रहा है। क्या वे अद्वितीय रहेंगे? क्या उन्होंने सभी खाता नंबर राज्य के संक्षिप्त नाम के साथ शुरू किए हैं, केवल ग्राहक की चाल के लिए। फ़ील्ड अपडेट करें - कोई समस्या नहीं - खाता संख्या द्वारा लिंक की गई सभी तालिकाएँ - क्या गड़बड़ है।
जेफ़ओ

1
पीके के रूप में एक स्ट्रिंग का उपयोग करने का एक उदाहरण सेटिंग्स की एक तालिका हो सकती है। उदाहरण के लिए सेटिंगनामनाम, आईएसयूसेटरटेबल, इस्क्यूएटरएडिटेबल इत्यादि। यदि आप सेटिंग व्यवहार को संशोधित करना चाहते हैं तो "UPDATE सेटिंग सेट करें ... जहां सेटिंगनामईकेपी = 'dailyWorkObligation'" आईडी के उपयोग और आईडी की मैपिंग को कहीं स्टोर करने की तुलना में बहुत अच्छा है। बेशक आपके पास एक पूर्णांक पीके हो सकता है और सेटिंग नाम के रूप में एक और अनूठी कुंजी भी हो सकती है।
मीटपॉप्सिकल

प्राथमिक कुंजी के साथ एक ऑटो-इंक्रीज किया गया पूर्णांक, आवेषण भी उनकी गति में अप्रभावित नहीं होना चाहिए?
डेनिस

उत्सुक रेल देवों के लिए, यहां एक इंडेक्स लंबाई निर्दिष्ट करने का तरीका बताया गया है । ध्यान दें कि SQLite सूचकांक लंबाई का समर्थन नहीं करता है।
डेनिस

1

प्रदर्शन के दृष्टिकोण से - हां स्ट्रिंग (पीके) एक पूर्णांक (पीके), जहां पीके ---> प्राथमिक कुंजी का उपयोग करके प्राप्त प्रदर्शन की तुलना में प्रदर्शन धीमा कर देगा।

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

इसलिए इष्टतम उपयोग के लिए - हम हमेशा 1 या 2 स्ट्रिंग विशेषताओं के साथ 1 या 2 पूर्णांक का एक संयोजन बनाते हैं, लेकिन केवल तभी जब यह आवश्यक हो।


0

डेटाबेस में स्ट्रिंग से संबंधित एक बहुत बड़ी गलतफहमी हो सकती है। लगभग सभी ने सोचा है कि संख्याओं का डेटाबेस प्रतिनिधित्व स्ट्रिंग्स की तुलना में अधिक कॉम्पैक्ट है। उन्हें लगता है कि db-s संख्याओं को स्मृति में दर्शाया गया है। लेकिन यह सच नहीं है। ज्यादातर मामलों में संख्या प्रतिनिधित्व ए स्ट्रिंग की तरह अधिक होता है जैसे कि प्रतिनिधित्व अन्य की तरह।

संख्या या स्ट्रिंग का उपयोग करने की गति अनुक्रमण पर अधिक निर्भर होती है, फिर स्वयं प्रकार।


0

डिफ़ॉल्ट रूप से ASPNetUserIds 128 char स्ट्रिंग्स हैं और प्रदर्शन ठीक है।

कुंजी तो कर दी गई तालिका में अद्वितीय होना यह कुंजी होना चाहिए। यहाँ पर क्यों;

प्राथमिक स्ट्रिंग कुंजी = सही DB संबंध, 1 स्ट्रिंग कुंजी (प्राथमिक), और 1 स्ट्रिंग सूचकांक (प्राथमिक)।

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

इसलिए एक int पहचान कुंजी का उपयोग करना = गलत DB संबंध, 1 int कुंजी (प्राथमिक), 1 int index (प्राथमिक), संभवतः एक अद्वितीय स्ट्रिंग इंडेक्स, और मैन्युअल रूप से एक ही स्ट्रिंग को मान्य करने के लिए मौजूद नहीं है (कुछ एक sql जाँच की तरह हो सकता है) )।

प्राथमिक कुंजी के लिए एक स्ट्रिंग के ऊपर एक पूर्णांक का उपयोग कर बेहतर प्रदर्शन प्राप्त करने के लिए, जब स्ट्रिंग HAS अद्वितीय होना, यह एक बहुत अजीब स्थिति होने के लिए होगा। मैंने हमेशा स्ट्रिंग कुंजियों का उपयोग करना पसंद किया है। और अंगूठे के एक अच्छे नियम के रूप में, जब तक आप की जरूरत नहीं है, तब तक एक डेटाबेस को नगण्य न करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.