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


145

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

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

अन्य सूचना:

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

विकल्प:

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

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

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

  4. प्रति डेटा प्रकार एक से अधिक UDF टेबल बनाएं। तो हमारे पास UDFStrings, UDFDates, आदि के लिए तालियाँ होंगी। संभवतः # 2 के रूप में भी ऐसा ही होगा और एक नया क्षेत्र जुड़ने पर कभी भी एक दृश्य को ऑटो-जनरेट करें।

  5. XML DataTypes? मैंने पहले इन के साथ काम नहीं किया है, लेकिन इनका उल्लेख किया है। निश्चित नहीं कि अगर वे मुझे वे परिणाम दें, जो मुझे चाहिए, खासकर प्रदर्शन के साथ।

  6. कुछ और?


7
मार्टिन फाउलर 2 (उपयोगकर्ता-अपूरणीय स्कीमा) या 5 (अनुक्रमित XML LOB) की सिफारिश करता है
नील मैकग्यूगन

डायनेमिक डेटाबेस स्कीमा पर StackOverflow प्रश्न भी देखें ।
फ़्लॉवरऑव

जवाबों:


49

यदि प्रदर्शन प्राथमिक चिंता है, तो मैं # 6 ... UDF प्रति तालिका (वास्तव में, यह # 2 का एक प्रकार है) के साथ जाना होगा। यह उत्तर विशेष रूप से इस स्थिति और वर्णित डेटा वितरण और एक्सेस पैटर्न के विवरण के अनुरूप है।

पेशेवरों:

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

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

  3. आप तालिका / स्तंभ नामों का उपयोग कर सकते हैं जो दर्शाते हैं कि वास्तव में डेटा क्या है।

  4. डेटा डोमेन को परिभाषित करने के लिए आपके पास डेटा प्रकारों, चेक बाधाओं, डिफ़ॉल्ट मानों आदि का पूर्ण नियंत्रण है। ऑन-द-फ्लाई डेटा प्रकार रूपांतरण से होने वाले प्रदर्शन को कम मत समझना। इस तरह की अड़चनें RDBMS क्वेरी ऑप्टिमाइज़र को अधिक प्रभावी योजनाएँ विकसित करने में मदद करती हैं।

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

विपक्ष:

  1. यह बहुत सारी सारणियाँ बना सकता है। स्कीमा पृथक्करण और / या नामकरण सम्मेलन को लागू करना इसको कम करेगा।

  2. यूडीएफ परिभाषा और प्रबंधन को संचालित करने के लिए अधिक आवेदन कोड की आवश्यकता है। मुझे उम्मीद है कि यह अभी भी मूल विकल्प 1, 3, और 4 की तुलना में कम कोड की आवश्यकता है।

अन्य बातें:

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

     'red', 'large', 45.03 

    बजाय

     NULL, 'medium', NULL

    ऐसे मामले में, आप 1 तालिका में 3 स्तंभों को मिलाकर एक ध्यान देने योग्य गति दंड नहीं लेंगे, क्योंकि कुछ मान NULL होंगे और आप 2 और तालिकाओं को बनाने से बचते हैं, जब आपको सभी 3 स्तंभों तक पहुंचने की आवश्यकता होती है, तो 2 कम जोड़ होते हैं ।

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

  3. लॉजिकल टेबल डिजाइन आपको एक निश्चित बिंदु पर ले जा सकता है, लेकिन जब रिकॉर्ड मायने रखता है तो बड़े पैमाने पर मिलता है, आपको यह भी देखना शुरू करना चाहिए कि आपकी पसंद के आरडीबीएमएस द्वारा कौन से टेबल विभाजन विकल्प प्रदान किए गए हैं।


1
जाँच सूची! मेरे और फिल के बीच मजाक के अंदर, मुझे आशा है कि नियमों के खिलाफ नहीं है।
गनरले ०३५१०

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

मैं उस तालिका के साथ काम कर रहा हूं, जिसने UDF की दिनांकित / संस्करणबद्ध की है, मैं नवीनतम मान प्राप्त करने के लिए, इस पद्धति का उपयोग करता हूं, stackoverflow.com/a/123481/328968
पीटर

22

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

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

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

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


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

2
शुरुआत के लिए, आप किसे विशेषता नहीं बना पाएंगे? आप सभी विशेषताओं को अद्वितीय बनाने के बिना एक विशेषता कैसे बनाएंगे? यह वहीं से चलता है। आप सुविधाओं के लिए RDBMS पहले से ही प्रदान करता है, यहां तक ​​कि एक तार्किक इकाई रिकॉर्ड डालने और इसे वापस लाने के लिए किसी प्रकार की मैपिंग क्लास लिखने की सुविधा प्रदान करने के लिए आप एप्लिकेशन कोड लिखना समाप्त करते हैं।
बिल कारविन

2
संक्षिप्त उत्तर है "डेटा और मेटाडेटा को न मिलाएं।" के लिए वर्चर कॉलम बनाना fieldnameया tablenameडेटा स्ट्रिंग्स के रूप में मेटाडेटा पहचानकर्ताओं को संग्रहीत करना है, और यह बहुत सारी समस्याओं की शुरुआत है। इसके अलावा en.wikipedia.org/wiki/Inner-platform_effect
बिल करविन

2
@ थोमस: उल्टे इंडेक्स डिज़ाइन में, आप डेटा प्रकारों के लिए मानक स्कीमा समाधानों का उपयोग कर सकते हैं, और UNIQUE और FOREIGN KEY जैसी बाधाओं का उपयोग कर सकते हैं। जब आप EAV का उपयोग करते हैं तो वे बिल्कुल भी काम नहीं करते हैं। मैं ईएवी के साथ इन्वर्टेड इंडेक्स शेयरों को गैर-संबंधपरक होने से सहमत हूं क्योंकि यह प्रति पंक्ति असमान विशेषताओं का समर्थन करता है, लेकिन यह समझौता का एक बिंदु है।
बिल कारविन

2
@thitami, जो मैंने पिछले कुछ वर्षों में सीखा है, वह यह है कि कोई भी उपाय आपके ऐप के लिए सही हो सकता है। यहां तक ​​कि ईएवी कुछ विशिष्ट ऐप के लिए सबसे कम बुरा समाधान हो सकता है। आप अपने प्रश्नों को जाने बिना एक अनुकूलन रणनीति नहीं चुन सकते। हर तरह का अनुकूलन अन्य प्रश्नों की कीमत पर कुछ प्रश्नों को बेहतर बनाता है।
बिल कार्विन

10

मैं संभवतः निम्नलिखित संरचना की तालिका बनाऊंगा:

  • वरचर नाम
  • varchar प्रकार
  • दशमलव नंबरवैल्यू
  • varchar StringValue
  • दिनांक DateValue

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

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

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

तालिका UdfMetaData

  • इंट आईडी
  • वरचर नाम
  • varchar प्रकार

तालिका MasterUdfValues

  • int Master_FK
  • int मेटाडाटा_एफके
  • दशमलव नंबरवैल्यू
  • varchar StringValue
  • दिनांक DateValue

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


मुझे आपकी रणनीति पसंद है, और शायद इसके लिए चुनते हैं लेकिन 2017 में, क्या आप कुछ अलग करने का विकल्प चुनेंगे? जैसे json
maztt

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

इसके अलावा, जो मैंने 2011 में प्रस्तावित किया था वह आईएमएचओ अभी भी एक वैध समाधान है।
स्टीफन स्टाइनगर्गर

10

यह एक समस्या की तरह लग रहा है जिसे गैर-संबंधपरक समाधान द्वारा हल किया जा सकता है, जैसे कि MongoDB या CouchDB।

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

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

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

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

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

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


6

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

विकल्प 1

IMO यह दृष्टिकोण आपको बिना किसी ज्ञान के स्कीमा देता है क्योंकि स्कीमा का मतलब क्या है जो आपदा के लिए एक नुस्खा है और रिपोर्ट डिजाइनरों के लिए एक बुरा सपना है। यानी, आपके पास यह जानने के लिए मेटा डेटा होना चाहिए कि कौन सा कॉलम किस डेटा को संग्रहीत करता है। यदि वह मेटाडेटा गड़बड़ हो जाता है, तो यह आपके डेटा को नली देने की क्षमता रखता है। साथ ही, गलत डेटा को गलत कॉलम में रखना आसान बनाता है। ("क्या? स्ट्रिंग 1 में दोषियों का नाम है? मुझे लगा कि यह शैली शीन की पसंदीदा दवाएं थीं।"

विकल्प 3,4,5

IMO, आवश्यकताएँ 2, 3 और 4 किसी EAV की भिन्नता को समाप्त करती हैं। यदि आपको इस डेटा पर क्वेरी, सॉर्ट या गणना करने की आवश्यकता है, तो एक EAV Cthulhu का सपना है और आपकी विकास टीम का और DBA का बुरा सपना है। प्रदर्शन के मामले में ईएवी की अड़चन पैदा होगी और आपको वह डेटा अखंडता नहीं देगा जो आपको जल्दी से अपनी इच्छित जानकारी प्राप्त करने की आवश्यकता है। क्वेरीज़ जल्दी से क्रॉस्टैब गॉर्डियन समुद्री मील की ओर मुड़ेंगी।

विकल्प 2,6

यह वास्तव में एक विकल्प छोड़ देता है: विनिर्देशों को इकट्ठा करें और फिर स्कीमा का निर्माण करें।

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

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

विरल स्तंभ


5
  1. प्रति डेटा प्रकार एक से अधिक UDF टेबल बनाएं। तो हमारे पास UDFStrings, UDFDates, आदि के लिए तालियाँ होंगी। संभवतः # 2 के रूप में भी ऐसा ही होगा और एक नया क्षेत्र जुड़ने पर कभी भी एक दृश्य को ऑटो-जनरेट करें।

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

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

varchar Name
varchar Type
decimal NumberValue
varchar StringValue
date DateValue

यह एक सही और उत्कीर्ण होना चाहिए। फिल द्वारा 2011 पर पिछला जवाब आज 2016 की अच्छी सलाह नहीं है।
याप कै लुन लियोन

क्या मुझे sql में ऐसी प्रक्रिया करने का एक सरल उदाहरण मिल सकता है?
निरोज

देर से उत्तर के लिए क्षमा करें, लेकिन आप उसी के लिए डेटाबेस संरचना चाहते हैं। मैं आपको @Niroj नहीं मिला। क्या आप कृपया विस्तार से बता सकते हैं कि आपको क्या चाहिए।
अमित ठेकेदार

4

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

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

संपादित करें

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

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

postgress

माई एसक्यूएल


1
मुझे संभवतः सैकड़ों अप्रयुक्त स्तंभ बनाने के विचार से नफरत है। यह मैंने SQL डेटाबेस डिज़ाइन के बारे में जो कुछ भी सीखा और पढ़ा है, उसके खिलाफ जाता है। अभी, हमारे पास 1300 से अधिक उपयोगकर्ता-परिभाषित मूल्य हैं, हालांकि उनमें से बहुत से केवल मौजूदा वस्तुओं के डुप्लिकेट हैं जिन्हें अलग-अलग नाम दिया गया है।
राहेल

एकल तालिका के लिए 1300 अलग-अलग यूडीएफ? क्या प्रत्येक उपयोगकर्ता के पास UDF, या केवल किसी प्रकार का पावर उपयोगकर्ता जोड़ने का विकल्प है?
ओफिर योकटन

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

2

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

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


ईमानदारी से, मैंने XML में बिल्कुल भी नहीं देखा है। मुख्य बात यह है कि मुझे यह सीखना होगा कि यह कैसे काम करता है और इसके खिलाफ कैसे क्वेरी की जाती है, और मैंने सुना है कि प्रदर्शन अन्य विकल्पों की तुलना में खराब हो सकता है
राहेल

1
मैं इसके लिए xml का उपयोग करने से बचता हूँ: यह काम कर सकता है, और मैंने पिछले दिनों xml में कुछ इस तरह से लागू किया है, लेकिन डेटा संरचनाओं के बढ़ने के कारण प्रदर्शन काफी खराब हो गया, और कोड की जटिलता अधिक थी।
केल

2

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

XML datatypes प्रदर्शन कारणों से इतने अच्छे नहीं हैं। यदि आप सर्वर पर गणना कर रहे हैं तो आप लगातार इनको डिसेर्बलाइज करने वाले हैं।

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


धन्यवाद, मैं SQL वेरिएंट पर एक और नज़र डालूंगा। मेरी सबसे बड़ी चिंता का प्रदर्शन है और मुझे यकीन नहीं है कि यह कैसे संभालेगा, खासकर अगर हम 50mil पंक्तियों के बारे में बात कर रहे हैं
राहेल

बस पता चला कि sql_varients को LIKE क्लॉज़ के साथ इस्तेमाल नहीं किया जा सकता है ... मेरे लिए बहुत बड़ा नकारात्मक पहलू है। बेशक, अगर मैं प्रत्येक यूडीएफ के लिए एक दृश्य बनाता हूं, तो मैं इसे SQL_VARIANT_PROPERTY (मूल्य, 'बेस टाइप') के आधार पर उपयुक्त डेटाटाइप में डाल सकता हूं ... फिर भी, प्रदर्शन के लिए इसका बुरा लगता है
राहेल

आप LIKE का उपयोग कर सकते हैं, लेकिन आपको पहले मूल्य डालना होगा। LIKE केवल varchars पर काम करता है इसलिए आपको अपने sql_variant को एक varchar पर कास्ट करना होगा। जब तक आप जानते हैं कि क्या आपका UDF एक varchar है (जैसे कि प्रकार कहीं और संग्रहीत है) तो आप अपनी सभी पंक्तियों को varchars में फ़िल्टर कर सकते हैं और फिर अपनी LIKE क्वेरी को चला सकते हैं: उदा। चयन करें * से MyTable जहाँ variant_type = 'v' Cast (variant_value as varchar (max)) LIKE 'Blah%' इस तरह, आप ints को परिवर्तित नहीं कर रहे हैं और इसी तरह तार जो धीमा हो जाएगा।
टिम रोजर्स

मुझे यह देखने के लिए कुछ परीक्षण चलाने होंगे कि प्रदर्शन कैसा है, विशेषकर लाखों पंक्तियों के साथ। Sql_varients का उपयोग करके प्रदर्शन के बारे में किसी भी ऑनलाइन लेख के बारे में जानें? विशेष रूप से कास्टिंग और बहुत बड़ी संख्या में रिकॉर्ड के साथ?
राहेल


1

मैंने इनमें से किसी भी विकल्प (विकल्प 6; :)) का उपयोग करके अतीत में इसे बहुत सफलतापूर्वक प्रबंधित किया है।

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

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


1

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

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

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

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


हाय @ एलेक्स, मैं एक समान मुद्दे पर आया था। अगर मुझे अच्छी तरह से समझ में आ गया है: 1) एक custom_fieldsटेबल स्टोरेज वैल्यू जैसे 1 => last_concert_year, 2 => band, 3 => musicऔर फिर एक custom_fields_valuesटेबल जिसका मान 001, 1, 1976 002, 1, 1977 003, 2, Iron Maiden003, 3 है , Metal आशा है कि उदाहरण आपको समझ में आता है और प्रारूपण के लिए खेद है!
थिटामी

@ उतमी बिल्कुल नहीं। आपके उदाहरण के बाद: मेरे पास एक bandsपंक्ति है 1,'Iron Maiden'फिर custom_fieldsपंक्तियों के साथ 1,'concert_year' | 2,'music'फिर custom_fields_valuesपंक्तियों के साथ1,1,'1977'|1,2,'metal'
एलेक्स

0

टिप्पणियों में मैंने आपको यह कहते हुए देखा कि यूडीएफ फ़ील्ड आयातित डेटा को डंप करने के लिए हैं जो उपयोगकर्ता द्वारा ठीक से मैप नहीं किया गया है।

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

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

अब मैं उपयोगकर्ताओं के लिए लिंक के साथ विकल्प 4 (EDIT) क्या करूंगा:

general_data_table
id
...


udfs_linked_table
id
general_data_id
udf_id


udfs_table
id
name
type
owner_id --> Use this to filter for the current user and limit their UDFs
string_link_id --> link table for string fields
int_link_id
type_link_id

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


0

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

SELECT *
FROM FieldValues_Text
WHERE fieldId IN (
    SELECT fieldId FROM Fields WHERE userId=@userId
)
AND value LIKE '%' + @search + '%'

यह मेरी राय में उपयोगकर्ता-परिभाषित प्रकारों के लिए सर्वोत्तम संभव प्रदर्शन सुनिश्चित करेगा।

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

रिपोर्टिंग के लिए, आप PIVOTअपने फ़ील्ड्स तालिका लेबल मानों को स्तंभ नामों में परिवर्तित करने के लिए उपयोग कर सकते हैं , फिर प्रत्येक डेटा प्रकार तालिका से उन क्वेरी स्तंभों में अपने क्वेरी परिणामों को पिवट करें।

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