आमतौर पर स्ट्रिंग कुंजी का उपयोग एक बुरा विचार क्यों माना जाता है?


24

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

दो सरल उदाहरण लें, अगर यह मदद करता है:

SQL जैसी तालिका जिसमें पंक्तियों को स्ट्रिंग प्राथमिक कुंजी द्वारा अनुक्रमित किया जाता है।

एक .NET डिक्शनरी जहां कीज स्ट्रिंग्स हैं।


9
स्ट्रिंग कीज़ का होना सामान्य रूप से एक बुरा विचार नहीं है। मुझे संदेह है कि उन बयानों को एक संदर्भ में किया गया था जहां एक बेहतर कुंजी उपलब्ध है। मेरे पास हर समय स्ट्रिंग कुंजियों के साथ .net शब्दकोश हैं। क्या आप इस दावे के कुछ उदाहरण दे सकते हैं?
कोडइन्चोअर्स

3
आप आमतौर पर प्राथमिक कुंजी चाहते हैं जो किसी वस्तु / पंक्ति के जीवनकाल में नहीं बदलती है। इसलिए उदाहरण के लिए usernameएक usersमेज की प्राथमिक कुंजी शायद सबसे अच्छा विचार नहीं है, और आप एक ऑटो-इंक्रीमेंट आईडी पसंद करेंगे। लेकिन उस usernameएक स्ट्रिंग है केवल आकस्मिक, एक परिवर्तनशील संपत्ति जा रहा है मुख्य मुद्दा है
CodesInChaos

एक डेटाबेस में, विचार करें कि पूर्णांक के विपरीत स्ट्रिंग्स को कैसे अनुक्रमणित किया जाएगा।

@CodesInChaos मेरी इच्छा है कि मैं याद करूं कि मुझे ज्यादातर मामले कहां मिले, लेकिन अब मैं थोड़ा सा पेस्ट कर सकता हूं जिसने मुझे इस मुद्दे की याद दिला दी। यह वाल्व द्वारा एक जीडीसी स्लाइड शो से था जिसमें खेल के संवादों और दुनिया के बारे में तथ्यों को संग्रहीत करने पर चर्चा की गई थी <key = string, value = object> जोड़े।

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

जवाबों:


17

यह सब मूल रूप से दो चीजों के साथ करना है:

1) देखने की गति (जहाँ उदाहरण के लिए पूर्णांक बेहतर है)

2) इंडेक्स का आकार (जहां स्ट्रिंग इंडेक्स फट जाएगा)

अब यह सब आपकी आवश्यकताओं और डेटासेट के आकार पर निर्भर करता है। यदि तालिका या संग्रह में 10-20 तत्व हैं, तो कुंजी का प्रकार अप्रासंगिक है। यह एक स्ट्रिंग कुंजी के साथ भी बहुत तेज होगा।

PS आपके प्रश्न से संबंधित नहीं हो सकता है, लेकिन गाइड को डेटाबेस कीज़ के लिए भी खराब माना जाता है (16 बाइट गाइड बनाम 4 बाइट पूर्णांक)। बड़े डेटा वॉल्यूम पर लोग लुकअप को धीमा कर देते हैं।


हमेशा नहीं - वृद्धिशील GUID संभव है। इंडेक्स अभी भी बड़े होंगे, लेकिन लुकअप पेनल्टी लगभग खराब नहीं होगी।
सैम

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

9

स्ट्रिंग के रूप में स्ट्रिंग का उपयोग करने, कुंजी के रूप में स्ट्रिंग शाब्दिक का उपयोग करने, शुद्ध प्रदर्शन / दक्षता कारणों को अलग करने के साथ एक और मुद्दा है। लेखन त्रुटियां। यदि आप एक शब्दकोश में कुंजी के रूप में स्ट्रिंग शाब्दिक का उपयोग करते हैं, तो आप अपने आप को एक आश्चर्यचकित कर सकते हैं जब एक "ReceiverId"बन जाता है "RecieverId"। प्रमुख मूल्यों को संग्रहीत करने और जब भी आप शब्दकोश का उपयोग करते हैं, तब उन्हें पुन: उपयोग करने के लिए स्थिरांक स्थापित करें।

तुच्छ और स्पष्ट, आप कह सकते हैं, फिर भी वेब के चारों ओर .NET कोड उदाहरणों की एक आश्चर्यजनक संख्या स्ट्रिंग डबल्स का उपयोग करती है, जो इस संदिग्ध अभ्यास का प्रचार करती है। सभी सत्रों, ViewStates और QueryParams के साथ ASP.NET कोडबेस के पार बिखरे हुए हैं, विशेष रूप से यहाँ दोषी है।


तुच्छ IMHO नहीं। मैंने उन मामलों को भी देखा है जहां चाबियाँ हैं "1"और "1 "एक ही तालिका में हैं।
pswg

जब आप मिश्रण में केस सेंसिटिविटी फेंकते हैं, तब और भी अधिक मनोरंजक हो जाते हैं। खुद सहित लोगों के भार सीधे उसी में टकराते हैं।
टोनी हॉपकिंसन

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

4

यहां कई ट्रेडऑफ हैं। वास्तव में मैं अक्सर स्ट्रिंग कुंजियों का उपयोग करता हूं, लेकिन अक्सर मैं जॉन्स के लिए सरोगेट द्वितीयक कुंजियों को शामिल करता हूं (जाहिर है कि यह आसपास का दूसरा तरीका होगा यदि मैं MySQL का उपयोग कर रहा था)। ऐसे मामले हैं जहां मैं हालांकि नहीं।

पहले मैं प्राकृतिक कुंजी को प्राथमिक कुंजी घोषित करने का प्रशंसक हूं, जहां db इसे अच्छी तरह से संभाल सकता है (उदाहरण के लिए PostgreSQL)। यह सामान्यीकरण में मदद करता है और स्पष्ट डेटाबेस डिजाइन के लिए बनाता है। सरोगेट कुंजियाँ जुड़ने को आसान बनाती हैं।

आम तौर पर सरोगेट कुंजी जोड़ने के दो कारण हैं:

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

  2. संयुक्त कुंजी पर प्रदर्शन में शामिल होना समस्याग्रस्त है और एक बार जब आप प्राकृतिक कुंजी मार्ग से नीचे जाते हैं, तो आप वहां फंस जाते हैं।

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

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

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


यदि आप पूर्णांक प्रकार को वापस शून्य के आसपास लपेटने का प्रबंधन करते हैं तो यह गैर-शून्य नहीं है। अहस्ताक्षरित 32-बिट प्रकार के लिए, जो केवल 4 जी दूर है, जो "रिकॉर्ड के अरबों" के साथ अशांति के करीब है ...
डोनाल्ड फेलो

यदि आपके पास एक db है जिसे आप "चारों ओर लपेटने के बजाय त्रुटि" बता सकते हैं यह शून्य है। किसी भी दर पर छद्म आयामी मूल्यों की तुलना में पूर्णांकों को बढ़ाने के साथ टकराव की संभावना का प्रबंधन करना आसान है।
क्रिस ट्रैवर्स

1

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


1

यह और अपने आप में एक बुरा विचार नहीं है, यह आमतौर पर 20/20 के साथ एक खराब डिजाइन समझौता है। अतिरिक्त लागत और जटिलता बनाम स्ट्रिंग और लचीलेपन की सीमा।

यदि पूर्णांक कार्य सीमा के अनुसार है और महंगी प्रसंस्करण के थोक को यह जानने की आवश्यकता नहीं है कि पूर्णांक क्या दर्शाता है, तो एक का उपयोग करें।


0

आपने किसी हैशटेबल से गलत डेटा को पुनः प्राप्त किया।

क्या आपका मतलब "DaytimeTelephone" या "EveningTelephone" था?

या

क्या आपका मतलब 1234567 या 1234576 है?

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


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

-1

बहुत सारे व्यापार बंद हो गए और कोई भी सही जवाब नहीं दे पाया। कई प्रोग्रामर डेटाबेस में स्ट्रिंग कुंजियों का उपयोग करने पर कभी विचार नहीं करेंगे क्योंकि वे हैशिंग के बारे में नहीं जानते हैं और डेटाबेस कैसे काम करता है। स्ट्रिंग कीज़ जब तक वे या तो बेहद स्थिर होती हैं, या अर्थहीन (सरोगेट), कई परिस्थितियों में एक अच्छी डिज़ाइन पसंद होती हैं।


2
यह उत्तर कुछ भी नहीं जोड़ता है जो पहले से ही अन्य उत्तरों में नहीं कहा गया है, जो इसे बेहतर कहते हैं।
मार्टिज़न पीटर

-2

जब यह लगभग 10-100 लघु स्ट्रिंग रिकॉर्ड के साथ लुकअप टेबल की बात आती है, तो स्ट्रिंग कुंजी का अर्थ होगा; संबंधित डेटा अधिक पठनीय है + जैसे परिवर्तन ट्रैकिंग (संख्यात्मक / गाइड आईडी बनाम स्ट्रिंग जैसे "प्रशासक"); btw, ASP.NET सदस्यता डेटाबेस AspNetRoles के लिए स्ट्रिंग कुंजियों का उपयोग करता है।

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