sql - उपयोगकर्ता परिभाषित फ़ील्ड के लिए डेटाबेस कैसे डिज़ाइन करें?



database design (9)

  1. एक डेटा प्रकार प्रति एक, कई यूडीएफ टेबल बनाएँ। तो हमारे पास यूडीएफएसट्रिंग्स, यूडीएफडेट्स इत्यादि के लिए टेबल होंगे। शायद # 2 के समान ही होगा और किसी भी फ़ील्ड को ऑटो-जेनरेट करने पर कभी भी एक नया फ़ील्ड जोड़ा जाएगा

मेरे शोध के मुताबिक डेटा प्रकार के आधार पर कई टेबल आपको प्रदर्शन में मदद करने के लिए नहीं जा रहे हैं। विशेष रूप से यदि आपके पास 50+ यूडीएफ के साथ 20K या 25K रिकॉर्ड जैसे थोक डेटा हैं। प्रदर्शन सबसे खराब था।

आपको एकल कॉलम के साथ कई स्तंभों के साथ जाना चाहिए जैसे:

varchar Name
varchar Type
decimal NumberValue
varchar StringValue
date DateValue

मेरी आवश्यकताएं हैं:

  • किसी भी डेटा प्रकार के उपयोगकर्ता-परिभाषित फ़ील्ड को गतिशील रूप से जोड़ने में सक्षम होना चाहिए
  • यूडीएफ को जल्दी से पूछने में सक्षम होना चाहिए
  • डेटाटाइप के आधार पर यूडीएफ पर गणना करने में सक्षम होना चाहिए
  • डेटाटाइप के आधार पर यूडीएफ को सॉर्ट करने में सक्षम होना चाहिए

अन्य सूचना:

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

विकल्प:

  1. StringValue1, StringValue2 के साथ एक बड़ी तालिका बनाएं ... IntValue1, IntValue2, ... आदि। मुझे इस विचार से नफरत है, लेकिन अगर कोई मुझे बता सकता है कि यह अन्य विचारों से बेहतर है और क्यों।

  2. एक गतिशील तालिका बनाएं जो आवश्यकतानुसार मांग पर एक नया कॉलम जोड़ती है। मुझे यह विचार पसंद नहीं है क्योंकि मुझे लगता है कि जब तक आप प्रत्येक कॉलम को अनुक्रमित नहीं करते हैं तो प्रदर्शन धीमा हो जाएगा।

  3. UDFName, UDFDataType, और मान वाली एक एकल तालिका बनाएं। जब कोई नया यूडीएफ जोड़ा जाता है, तो एक व्यू उत्पन्न करें जो केवल उस डेटा को खींचता है और जो भी प्रकार निर्दिष्ट होता है उसे पार करता है। आइटम जो पार्सिंग मानदंडों को पूरा नहीं करते हैं, वे वापस लौटते हैं।

  4. एक डेटा प्रकार प्रति एक, कई यूडीएफ टेबल बनाएँ। तो हमारे पास यूडीएफएसट्रिंग्स, यूडीएफडेट्स इत्यादि के लिए टेबल होंगे। शायद # 2 के समान ही होगा और किसी भी फ़ील्ड को ऑटो-जेनरेट किया जाएगा जब भी कोई नया फ़ील्ड जोड़ा जाता है

  5. एक्सएमएल डेटा टाइप? मैंने पहले इनके साथ काम नहीं किया है लेकिन उन्हें देखा है। यकीन नहीं है कि वे मुझे परिणाम चाहते हैं, विशेष रूप से प्रदर्शन के साथ।

  6. कुछ और?


SharePoint विकल्प 1 का उपयोग करता है और उचित प्रदर्शन करता है।


मेरे पास अनुभव या 1, 3 और 4 है और वे सभी गन्दा हो जाते हैं, यह स्पष्ट नहीं होता है कि डेटा को गतिशील प्रकार के रिकॉर्ड में डेटा को तोड़ने के लिए कुछ प्रकार के मुलायम वर्गीकरण के साथ डेटा वास्तव में जटिल है या वास्तव में जटिल है।

मैं एक्सएमएल आज़माने का लुत्फ उठाऊंगा, आपको डेटा टाइपिंग आदि की जांच करने के लिए एक्सएमएल की सामग्री के खिलाफ स्कीमा को लागू करने में सक्षम होना चाहिए जो यूडीएफ डेटा के अंतर सेट को रखने में मदद करेगा। एसक्यूएल सर्वर के नए संस्करणों में आप एक्सएमएल फ़ील्ड पर इंडेक्स कर सकते हैं, जो प्रदर्शन पर मदद करनी चाहिए। (उदाहरण के लिए http://blogs.technet.com/b/josebda/archive/2009/03/23/sql-server-2008-xml-indexing.aspx देखें)


मैं शायद निम्न संरचना की एक तालिका बनाउंगा:

  • वर्कर नाम
  • वर्कर प्रकार
  • दशमलव संख्या वैल्यू
  • वर्कर स्ट्रिंगवैल्यू
  • तिथि DateValue

पाठ्यक्रम के सटीक प्रकार आपकी आवश्यकताओं पर निर्भर करते हैं (और निश्चित रूप से आप जिस डीबीएमएस का उपयोग कर रहे हैं) पर निर्भर करते हैं। आप int और booleans के लिए NumberValue (दशमलव) फ़ील्ड का भी उपयोग कर सकते हैं। आपको अन्य प्रकारों की भी आवश्यकता हो सकती है।

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

आप किसी प्रकार की मेटा डेटा जानकारी चाहते हैं। तो आप निम्नलिखित के साथ समाप्त होता है:

टेबल UdfMetaData

  • int आईडी
  • वर्कर नाम
  • वर्कर प्रकार

टेबल मास्टर यूडीएफ वैल्यूज

  • int मास्टर_एफके
  • int मेटाडेटा_एफके
  • दशमलव संख्या वैल्यू
  • वर्कर स्ट्रिंगवैल्यू
  • तिथि DateValue

आप जो कुछ भी करते हैं, मैं गतिशील रूप से तालिका संरचना को नहीं बदलूंगा। यह एक रखरखाव दुःस्वप्न है। मैं एक्सएमएल संरचनाओं का भी उपयोग नहीं करता , वे बहुत धीमी हैं।


मैंने इस समस्या के बारे में बहुत कुछ written । सबसे आम समाधान एंटिटी-एट्रिब्यूट-वैल्यू एंटीपाटरर्न है, जो आपके विकल्प # 3 में वर्णित है। प्लेग की तरह इस डिजाइन से बचें

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

आप यहां इस समाधान के बारे में 200 9 से एक दिलचस्प लेख पढ़ सकते हैं: http://backchannel.org/blog/friendfeed-schemaless-mysql

या आप दस्तावेज़-उन्मुख डेटाबेस का उपयोग कर सकते हैं, जहां यह अपेक्षित है कि आपके पास प्रति दस्तावेज़ कस्टम फ़ील्ड हैं। मैं Solr


यदि आप SQL सर्वर का उपयोग कर रहे हैं, तो sqlvariant प्रकार को अनदेखा न करें। यह बहुत तेज़ है और आपको अपना काम करना चाहिए। अन्य डेटाबेस में कुछ समान हो सकता है।

एक्सएमएल डेटाटाइप प्रदर्शन कारणों से बहुत अच्छे नहीं हैं। यदि आप सर्वर पर गणना कर रहे हैं तो आप लगातार इन्हें deserialize कर रहे हैं।

विकल्प 1 खराब लगता है और क्रोधित दिखता है, लेकिन प्रदर्शन-वार आपकी सर्वश्रेष्ठ शर्त हो सकता है। मैंने फील्ड00-फील्ड 99 नामक कॉलम के साथ तालिकाओं को बनाया है क्योंकि आप प्रदर्शन को हरा नहीं सकते हैं। आपको अपने आईएनएसईआरटी प्रदर्शन पर भी विचार करने की आवश्यकता हो सकती है, इस मामले में यह भी जाना है। यदि आप इसे साफ दिखाना चाहते हैं तो आप हमेशा इस तालिका पर दृश्य बना सकते हैं!


यह एक समस्याग्रस्त स्थिति है, और कोई भी समाधान "दाएं" दिखाई देता है। हालांकि विकल्प 1 सादगी और प्रदर्शन के संदर्भ में शायद सबसे अच्छा है।

यह कुछ व्यावसायिक उद्यम अनुप्रयोगों में भी उपयोग किया जाने वाला समाधान है।

संपादित करें

एक और विकल्प जो अब उपलब्ध है, लेकिन अस्तित्व में नहीं था (या कम से कम परिपक्व नहीं था) जब सवाल पूछा गया था कि डीबी में जेसन फ़ील्ड का उपयोग करना है।

कई रिलेशनल डीबी अब जेसन आधारित फ़ील्ड का समर्थन करते हैं (जिसमें उप फ़ील्ड की गतिशील सूची शामिल हो सकती है) और उन पर पूछताछ की अनुमति दें

postgress

mysql


यह ऐसी समस्या की तरह लगता है जो गैर-रिलेशनल समाधान द्वारा बेहतर हल किया जा सकता है, जैसे मोंगोडीबी या कॉच डीबी।

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

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

आप यह निर्धारित नहीं कर सकते कि शून्य या अनुपलब्ध मान आपकी ऑब्जेक्ट परत में स्कीमा नियमों को एम्बेड किए बिना एक वैध प्रविष्टि या प्रविष्टि की कमी है या नहीं।

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

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

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


हमारा डेटाबेस एक सास ऐप (हेल्पडेस्क सॉफ़्टवेयर) को सशक्त करता है जहां उपयोगकर्ता 7k "कस्टम फ़ील्ड" से अधिक होते हैं। हम एक संयुक्त दृष्टिकोण का उपयोग करते हैं:

  1. (EntityID, FieldID, Value) तालिका डेटा खोजने के लिए
  2. entities तालिका में एक JSON फ़ील्ड, जिसमें सभी इकाई मान होते हैं, जो डेटा प्रदर्शित करने के लिए उपयोग किए जाते हैं। (इस तरह आपको मूल्य मान प्राप्त करने के लिए दस लाख जॉइन की आवश्यकता नहीं है)।

आप इस जवाब की तरह "टेबल प्रति डेटाटाइप" रखने के लिए # 1 को आगे विभाजित कर सकते हैं, इस तरह आप अपने यूडीएफ को भी इंडेक्स कर सकते हैं।

पीएस युगल शब्द "एंटिटी-एट्रिब्यूट-वैल्यू" दृष्टिकोण की रक्षा करने के लिए हर कोई झुकाव रखता है। हमने दशकों से # 2 के बिना # 1 का उपयोग किया है और यह ठीक काम करता है। कभी-कभी यह एक व्यावसायिक निर्णय है। क्या आपके पास अपने ऐप को फिर से लिखने और डीबी को फिर से डिजाइन करने का समय है या आप क्लाउड-सर्वर पर कुछ रुपये के माध्यम से कर सकते हैं, जो इन दिनों वास्तव में सस्ते हैं? वैसे, जब हम # 1 दृष्टिकोण का उपयोग कर रहे थे, तो हमारे डीबी लाखों इकाइयों को पकड़ रहे थे, जो हजारों उपयोगकर्ताओं द्वारा उपयोग किए गए थे, और 16 जीबी ड्यूल-कोर डीबी सर्वर बस ठीक कर रहा था (वास्तव में एडब्ल्यूएस पर "आर 3" वीएम) ।





user-defined-fields