अलग-अलग पंक्तियों के बजाय एक पंक्ति के एक क्षेत्र में कई मूल्यों को संग्रहीत करने के संभावित लाभ


11

हमारी पिछली साप्ताहिक बैठक के दौरान, एक व्यक्ति जिसके पास डेटाबेस प्रशासन में कोई पृष्ठभूमि का अनुभव नहीं है, इस प्रश्न को लाया:

"क्या कोई ऐसा परिदृश्य होगा जो कई लाइनों के बजाय डेटा इन-लाइन (स्ट्रिंग) को सही ठहराता है?"

आइए हम एक तालिका को कहते हैं countryStatesजहां हम किसी देश के राज्यों को संग्रहीत करना चाहते हैं; मैं इस उदाहरण के लिए यूएसए का उपयोग करूंगा और आलस्य के लिए सभी राज्यों को सूचीबद्ध नहीं करूंगा।

वहां हमारे दो कॉलम होंगे; एक ने फोन किया Countryऔर दूसरे ने फोन किया States। जैसा कि यहां चर्चा की गई है , और @ srutzky के उत्तर द्वारा प्रस्तावित , आईएसओ 3166-1 अल्फा -3PK द्वारा परिभाषित कोड होगा ।

हमारी तालिका इस तरह दिखाई देगी:

+---------+-----------------------+-------------------------------------------------------+
| Country | States                | StateName                                             |
+---------+-----------------------+-------------------------------------------------------+
| USA     | AL, CA, FL,OH, NY, WY | Alabama, California, Florida, Ohio, New York, Wyoming |
+---------+-----------------------+-------------------------------------------------------+

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

हमने निष्कर्ष निकाला कि यह मॉडल बहुत उपयोगी नहीं है, लेकिन मुझे संदेह है कि इस उपयोगी बनाने का कोई तरीका हो सकता है।

मैं पूछना चाहता हूं कि क्या आप में से किसी ने पहले से ही इस तरह से कुछ देखा, सुना या किया है जो वास्तव में काम करता है


अब कल्पना करें कि आपके पास एक दूसरी तालिका, "बिक्री" है, जिसमें हर बिक्री के लिए डेटा है जो राज्य कोड के साथ हुआ था जिसमें बिक्री हुई थी। आप एक क्वेरी कैसे लिखेंगे जो कॉलम (StateName, TotalSalesAmount) के साथ एक रिपोर्ट तैयार करती है? मुश्किल है, है ना?
०६:४६ पर झग्गी

बिल्कुल सही। मैं भी इस मॉडल से सहमत नहीं हूं। हम किसी भी बिंदु पर अटक जाते हैं, जिसे हमें किसी भी प्रकार के डेटा (या यदि आप चाहें तो उपयोगी डेटा) को पुनर्प्राप्त करने की आवश्यकता है।
Human_AfterAll

एक संभावित परिदृश्य चर को स्टोर करने के लिए हो सकता है। स्टोर a;b;cहै, तो अपने स्ट्रिंग आप पार्स प्राप्त करने के लिए सामने अंत का उपयोग a, b, c, निष्पादन पर और कैरी उनके साथ कुछ कर रही हो सकता है ?. महसूस करें कि यह उस तरह की विशिष्ट आवश्यकता के अनुरूप हो सकता है ... दूसरे विचार पर, नहीं। आप हमेशा आईडी स्टोर कर सकते हैं, अपनी तालिकाओं में शामिल हो सकते हैं और एक
सुस्पष्ट

निष्पक्ष होने के लिए (मेरे लिए, कम से कम ;-), मैंने 2-वर्ण वाले देश कोड का उपयोग करने का प्रस्ताव दिया :-) उस अन्य उत्तर में
सोलोमन रटज़की

2
ध्यान दें कि कॉलम STATE, N & C के लिए "स्टेट STATE के नाम में Nth वर्ण C" के साथ एक अलग तालिका होने के बजाय किसी कॉलम में "अलबामा" मान रखने के लिए किसी के पास कोई योग्यता नहीं है। क्योंकि या तो 1. हम नामों के पात्रों के बारे में प्रश्न करने का इरादा नहीं रखते हैं या 2. हम एक फ़ंक्शन को कॉल करने से बुरा नहीं मानते हैं NTH_CHAR (N, S) यदि हम करते हैं तो एक नाम के साथ हर पंक्ति में "स्ट्रिंग S का Nth वर्ण" लौटाते हैं। । (Vs जोइन और अन्य संबंधपरक ऑपरेटर अतिरिक्त तालिका के माध्यम से कुछ ऐसी पंक्तियों को समाप्त करते हैं।) पूर्णांक और NTH_DIGIT (N, I) के लिए Ditto। यह हमेशा एक निर्णय कॉल होता है जैसे कि किसी विशेष डेटाबेस में क्या संबंधपरक रूप से परमाणु है।
फिलिप

जवाबों:


13

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

एक शब्द में: नहीं। यदि आप वास्तविक डेटा बिंदुओं को संग्रहीत कर रहे हैं, तो यह केवल दर्द (कोड और प्रदर्शन के संदर्भ में) लाएगा क्योंकि यह अनावश्यक जटिलता है। यदि यह एक मूल्य है जो केवल एक ही इकाई के रूप में संग्रहीत किया जाएगा, एक इकाई के रूप में अद्यतन किया जाता है, और कभी भी डेटाबेस के भीतर विघटित नहीं किया जाता है, तो यह ठीक हो सकता है क्योंकि यह किसी छवि या पीडीएफ को संग्रहीत करने के लिए लगभग समान है। अन्यथा, डेटा को पार्स करने का कोई भी प्रयास किसी भी इंडेक्स (जैसे LIKE '%something%', या CHARINDEX, या PATINDEX, या SUBSTRING, आदि) का उपयोग करके अमान्य होगा ।

यदि आपको एक पंक्ति के एक ही क्षेत्र में अलग-अलग मान संग्रहीत करने की आवश्यकता है, तो ऐसा करने के अधिक उपयुक्त साधन हैं: XML या JSON। ये पार्स करने योग्य प्रारूप ( XML / JSON ) हैं और XML को अनुक्रमित भी किया जा सकता है । लेकिन आदर्श रूप से यह डेटा ठीक से टाइप किए गए फ़ील्ड में संग्रहीत किया जाएगा ताकि यह वास्तव में उपयोगी हो सके।

और कृपया यह न भूलें कि RDBMS का उद्देश्य ऐसे डेटा को संग्रहित करना है, जिसे ACID -compliant होने के कारण लगाए गए अवरोधों के भीतर, इसे यथासंभव कुशलता से पुनर्प्राप्त और हेरफेर किया जा सकता है । पहले मानों को पार्स करने की आवश्यकता के कारण संक्षिप्त मान वापस लेना बहुत बुरा है, और यह अनुक्रमणिका नहीं है। लेकिन अक्सर हेरफेर करने का मतलब है कि पूरे बूँद को केवल इसके एक हिस्से को अपडेट करना (यह मानते हुए कि कोई पैटर्न किसी फ़ंक्शन के साथ उपयोग करने के लिए मौजूद नहीं है )। XML डेटाटाइप कम से कम XML DML को सरलीकृत अपडेट के लिए अनुमति देता है , हालांकि वे अभी भी ठीक से मॉडल डेटा के एक साधारण अपडेट के रूप में तेजी से नहीं हैं।REPLACE

इसके अलावा, जैसा कि ऊपर दिए गए प्रश्न में दर्शाया गया है, जैसे सभी स्टेटकोड को एक साथ सम्‍मिलित करके, आप फॉरेन की (किसी भी दिशा में) उन मानों में असमर्थ होंगे।

और क्या होगा अगर समय के साथ व्यवसाय की आवश्यकताएं बदल जाती हैं और आपको इन वस्तुओं के अतिरिक्त गुणों को ट्रैक करने की आवश्यकता होती है? "राज्यों" के संदर्भ में, राजधानियों, या जनसंख्या, या एक क्रम-क्रम, या कुछ और के बारे में क्या? ठीक से संग्रहीत पंक्तियों के रूप में आप अतिरिक्त गुणों के लिए अधिक कॉलम जोड़ सकते हैं। निश्चित रूप से, आपके पास पार्सबल डेटा के कई स्तर हो सकते हैं, जैसे कि |StateCode,Capital,Population |StateCode,Capital,Populate|...लेकिन उम्मीद है कि समस्या को नियंत्रण से बाहर बढ़ते हुए कोई भी देख सकता है। बेशक, इस विशेष मुद्दे को एक्सएमएल और जेएसएन प्रारूपों से आसानी से निपटा जाता है, और जैसा कि ऊपर उल्लेख किया गया है, उनका मूल्य है। लेकिन आपको अभी भी मॉडलिंग के शुरुआती साधनों के रूप में उन दोनों में से किसी एक का उपयोग करने के लिए बहुत अच्छे कारण की आवश्यकता होगी क्योंकि न तो कभी भी अलग-अलग पंक्तियों में असतत खेतों का उपयोग करने के लिए उतना ही कुशल होगा।


9

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

OutputType   OutputHeader
PersonalData Name|Address|City|State|Zip
JobInfo      Name|JobName|JobTitle

अनिवार्य रूप से ऐसा लग रहा था कि यह एक सीमांकित सूची थी। और एक तरह से यह था। लेकिन हमारे उद्देश्यों के लिए यह एक लंबी स्ट्रिंग थी।

यही चाल यहाँ है। यदि आपने कभी सूची को पार्स करने की योजना नहीं बनाई है तो यह सूची को बचाने के लायक है। यदि फिर भी आपको सूची को पार्स करने की आवश्यकता हो सकती है, तो इसे अलग करने और इसे अलग-अलग पंक्तियों में सहेजने के लिए अतिरिक्त स्थान और समय के लायक है।


1

मैंने इसका उपयोग एक बार नहीं बल्कि एक छोटी सी तालिका के साथ किया है, उदाहरण के लिए:

CREATE TABLE t1 (
  ID number,
  some_feature   varchar2(100),
  valid_channels  varchar2(100));

CREATE TABLE channel_def (
  channel varchar2(100));

और फिर मूल्यों CRM,SMS,SELF-CAREको स्टोर करें valid_channel

पूरी तालिका में 10 रिकॉर्ड की तरह कुछ है। valid_channelऐसे मूल्य शामिल हैं जो वास्तव में एक लिंकिंग टेबल में होने चाहिए जो कई-से-कई संबंधों को दर्शाते हैं। तालिका t1का गहनता से उपयोग नहीं किया जा रहा है, इसलिए हमने इस सड़क के नीचे जाने का निर्णय लिया है। इस फैसले में कुछ राजनीति शामिल थी, हालांकि (नीचे देखें)।

लेकिन सामान्य तौर पर मैं इससे बचता हूं, यह 3NF नहीं है।

जिस स्थान पर मैं वर्तमान में काम करता हूं, उस स्थान पर दर्जनों ऐसे स्तंभ हैं। उनका औचित्य यह है कि यह उनके प्रश्नों को आसान बनाता है: लिंकिंग टेबल का उपयोग करके तीन तालिकाओं में शामिल होने के बजाय वे परिभाषा तालिका का उपयोग करके सीधे जा सकते हैं LIKE। उदाहरण के लिए

SELECT * 
  FROM t1 
 INNER JOIN channel_def cd
    ON ','||t1.valid_channels||',' LIKE '%,'||cd.channel||',%';

ओरेकल पर भयानक + यह शुरुआत के कारण सूचकांक के उपयोग को अक्षम करता है '%,'


कौन सा धीमा होगा: LIKEया एक साधारण सम्मिलित हों?
मानवी_ आफ्टरनैल

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

@Human_AfterAll सभी के LIKEलिए धीमा होगा, खासकर अगर डेटा ठीक से TINYINTपीके क्षेत्र का उपयोग करने के लिए मॉडलिंग की जाती है channel_def। फिर इसे केवल दो तालिकाओं के बीच एक एकल बाइट की तुलना करने की आवश्यकता है। यहाँ इसे स्ट्रिंग, कैरेक्टर को कैरेक्टर (कम से कम जब तक कंडीशन संतुष्ट नहीं किया जाता है) को पार्स करना है, और यह एक केस-इनसेंसिटिव सर्च कर रहा है (दिए गए टेबल डिफ के आधार पर एक _BIN2कोलाज का उपयोग नहीं दिखाया जा रहा है)। यह SQL सर्वर पर अनुक्रमित को भी अमान्य करता है। मैंने अपने जवाब में यह कहकर संबोधित किया कि पार्सिंग इंडेक्स का उपयोग नहीं कर सकता। मैंने इसे स्पष्ट करने के लिए सिर्फ अपना उत्तर अपडेट किया।
सोलोमन रटज़की

1
@ हनुमान_अब मैं कहूंगा कि यह मॉडलिंग निर्णय अनुभव और ज्ञान की कमी (और कभी-कभी उदासी) से पैदा हुआ था। एक अतिरिक्त JOIN वह सब है जो सहेजा गया है, लेकिन जो बलिदान किया गया है वह विदेशी कुंजी की क्षमता है जो पूरी तरह से फर्जी डेटा को प्राप्त करने से रोकेगा (भले ही यह LIKEक्लॉज से मेल न खाए और विषम परिणाम उत्पन्न न करे , यह अभी भी अन्य मुद्दों का कारण बन सकता है) कम से कम डिबगिंग को कठिन / लम्बा बनाएं)। यह valid_channelsक्षेत्र को और अधिक जटिल बनाता है। यह कहना नहीं है कि यह काम नहीं करता है, इसे करने का कोई अच्छा कारण नहीं है।
सोलोमन रटज़की

"अनुभव की कमी" - क्या सबसे बुरा है कि यह विशेष रूप से डिजाइन का निर्णय एक वरिष्ठ स्टाफ सदस्य द्वारा लगाया गया ...
रोबर्ट्रॉन

1

यह यहां एसई पर किया गया था। जैसा कि मार्क ग्रेवेल लिखते हैं :

... कुछ विचार और विचार के बाद, हम एक पाइप (बार) पर स्थिर हो गए, प्राकृतिक प्रतिनिधित्व को प्रमुख / अनुगामी पाइपों के साथ, इसलिए ".net c #" बस "| .net | c # |" | इसके गुण हैं:

  • बहुत सरल है
  • टैगों के थोक अद्यतन और हटाने को सरल टैग के साथ किया जा सकता है (पाइप सहित, मध्य-टैग मैचों को बदलने से बचने के लिए)
  • ...

यह "नया प्रारूप" "पुराने प्रारूप" से अगला चरण था, जो थोड़ा अलग था और इसे SQL सर्वर पूर्ण-पाठ खोज सुविधा का उपयोग करने के लिए चुना गया था, इसलिए यदि आप इसे खरोंच से करते हैं तो कुछ लाभ प्रासंगिक नहीं हैं।

उन्होंने संभवतः काम की राशि और प्रदर्शन कारणों दोनों के लिए पूरी तरह से सामान्य नहीं किया।


0

खैर, स्ट्रिंग्स और अन्य डेटा प्रकारों का उपयोग करने का एक संभावित प्राथमिक लाभ, उन्हें SQL सर्वर से C #, C, C ++ (आदि) में SQLCLR का उपयोग करके भेजा जाता है, जब सरासर प्रदर्शन की आवश्यकता होती है। आप संबंधपरक डेटा को गैर-संबंधपरक रूप से दर्शाने के लिए एक दृश्य या संग्रहीत कार्यविधि भी बना सकते हैं - जैसा कि आप इस उदाहरण के लिए ऊपर अपने उदाहरण के साथ कर रहे हैं।

इस उदाहरण को देखें:

http://aboutsqlserver.com/2013/07/22/clr-vs-t-sql-performance-considerations/

प्रति विकिपीडिया: SQL CLR या SQLCLR (SQL आम भाषा रनटाइम) SQL सर्वर के भीतर Microsoft .NET आम भाषा रनटाइम इंजन की मेजबानी के लिए प्रौद्योगिकी है। SQLCLR प्रबंधित कोड को Microsoft SQL सर्वर वातावरण द्वारा होस्ट और चलाने की अनुमति देता है।


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

लेख लिंक पेशेवरों और विपक्ष के साथ लाभों की व्याख्या करता है। इसके अलावा, मैंने डेटा को तर्कसंगत रूप से संग्रहीत करने का उल्लेख किया है, और सीएलआर के उद्देश्यों के लिए इसे एक दृश्य, या संग्रहीत प्रक्रिया के साथ गैर-संबंधपरक में परिवर्तित करना है। आपका प्रश्न था "क्या कोई ऐसा परिदृश्य होगा जो कई लाइनों के बजाय डेटा इन-लाइन (स्ट्रिंग) को सही ठहराता है?" और मेरा जवाब हां था, हालांकि मैं सीएलआर के साथ बातचीत के प्रयोजनों के लिए एक दृश्य या संग्रहीत प्रक्रिया पसंद करता हूं।
स्टिंग

0

मेरे विचार में, उत्तर नहीं होगा। मैंने इस दृष्टिकोण का उपयोग नहीं किया है और इसे टालूंगा - मैं एक कारण नहीं सोच सकता कि मैं उस मार्ग से नीचे क्यों जाऊँ। आप एक सरणी के साथ JSON / NoSQL की दुनिया की ओर झुक रहे हैं।

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

यदि आपको इस प्रकार के डेटा से जुड़ना है, तो यह एक बदसूरत अनुभव होगा। स्ट्रिंग के एकल तत्वों को अद्यतन करना भी अप्रिय होगा।

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