क्या उपयोगकर्ता परिभाषित क्षेत्रों की अनुमति देने के लिए यह बुरा अभ्यास है?


17

सामान्यतया, क्या किसी वेबएप के लिए किसी डेटाबेस में उपयोगकर्ता द्वारा बनाए गए फ़ील्ड के लिए अनुमति देना बुरा व्यवहार माना जाता है?

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

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

आम तौर पर हालांकि, लोग "वास्तविक जीवन" में इस तरह से कुछ कैसे संभालते हैं?


4
क्या आपने दस्तावेज़-उन्मुख डेटाबेस जैसे MongoDB का उपयोग करने पर विचार किया है? आप प्रति प्रकार एक दस्तावेज़ संग्रहीत कर सकते हैं जो स्कीमा के रूप में कार्य करता है जिसे संपादित भी किया जा सकता है (संभवतः मैन्युअल रूप से, परियोजना के छोटे पैमाने को देखते हुए)।
एंडी हंट

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

सभी: महान चर्चा, सभी अंतर्दृष्टि के लिए धन्यवाद! @AndyBursh मैंने MongoDB के बारे में सुना है, लेकिन वास्तव में इस पर कभी नहीं पढ़ा। एक और घर परियोजना की तरह लगता है ...
zako42

जवाबों:


19

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

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

निम्नलिखित तालिका पर विचार करें:

  + -------------- +
  | बात |
  | -------------- |
  | आईडी |
  | प्रकार |
  | desc |
  | Attr1 |
  | Attr2 |
  | Attr3 |
  | attr4 |
  | attr5 |
  + -------------- +

यह आपके द्वारा कुछ विशेषताएँ जोड़ने के बाद है। इसके बजाय attr1नाटक इसे पढ़ता है artistया tracksया genreया जो भी जिम्मेदार बताते बात है। और 5 के बजाय, क्या हुआ अगर यह 50 था। स्पष्ट रूप से यह असहनीय है। यह एक नए क्षेत्र को संभालने के लिए एप्लिकेशन के मॉडल और पुन: तैनाती के अद्यतन की भी आवश्यकता है। आदर्श नहीं।

अब निम्नलिखित तालिका संरचना पर विचार करें:

  + -------------- + + --------------- + + ------------- +
  | बात | | thing_attr | | अटर |
  | -------------- | | --------------- | | ------------- |
  | आईडी | <--- + | thing_id (fk) | +> | आईडी |
  | प्रकार | | attr_id (fk) | + - + | नाम |
  | desc | | मूल्य | | |
  + -------------- + + --------------- + + ------------- +

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

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

प्रश्न थोड़े अधिक जटिल हैं और सत्यापन अधिक जटिल भी हो जाता है (या तो काया संग्रहित प्रक्रियाएँ या सभी ग्राहक पक्ष)। डिजाइन में इसका व्यापार बंद है।

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


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

यदि आप nosql डेटाबेस के उपयुक्त स्वाद के साथ काम कर रहे हैं, तो आप शायद ऐसा कर सकते हैं (ध्यान दें कि इसके लिए nosql का उपयुक्त स्वाद संभवतः एक महत्वपूर्ण-मूल्य वाला स्टोर होगा, जो कि ऊपर वर्णित प्रासंगिक लोगों के लिए EAV तालिका है। बहुत अधिक परेशानी के बिना। हालाँकि, यह नोस्कल के लिए सभी समझौतों के साथ आता है, जो कहीं और बड़े विस्तार से वर्णित हैं।

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

  • आप मेटा-डेटाबेस प्रोग्रामिंग कर रहे हैं। एक अच्छे ORM के साथ इस कॉलम को उस क्षेत्र में साफ़-साफ़ मैप करने में सक्षम होने के बजाय, आप शायद ऐसी चीजें कर रहे हैं select *और फिर कुछ जटिल कोड बना रहे हैं ताकि यह पता लगाया जा सके कि वास्तव में डेटा क्या है ( जावा का ResultSetMetaData देखें ) और फिर नक्शे में संग्रहीत करना या कुछ अन्य डेटा टाइप - लेकिन कोड में अच्छे क्षेत्र नहीं )। इसके बाद आपके पास पारंपरिक दृष्टिकोण के साथ उचित प्रकार और टाइपो सुरक्षा को फेंक देता है।
  • आपने संभवतः ORM को छोड़ दिया है। इसका मतलब है कि आप सिस्टम को आपके लिए काम करने देने के बजाय सभी कोड के लिए कच्चे sql लिख रहे हैं।
  • आपने क्लीन अपग्रेड करने पर ध्यान दिया है। क्या होता है जब ग्राहक आपके नाम के साथ एक फ़ील्ड जोड़ता है जो आपका अगला संस्करण भी उपयोग करता है? मैचमेकिंग साइट में अपग्रेड जो hasdateटाइमस्टैम्प के भंडारण के लिए एक क्षेत्र जोड़ना चाहता है, पहले से ही hasdateएक सफल मैच के लिए बूलियन के रूप में परिभाषित किया गया है ... और आपका अपग्रेड टूट जाता है।
  • आप भरोसा कर रहे हैं कि ग्राहक कुछ आरक्षित शब्द का उपयोग करके सिस्टम को नहीं तोड़ता है जो आपके प्रश्नों को भी तोड़ देता है ... कहीं।
  • आपने खुद को एक डेटाबेस ब्रांड के लिए बाध्य किया है। DDL विभिन्न डेटाबेस के अलग है। डेटाबेस प्रकार इस का सबसे आसान उदाहरण हैं। varchar2बनाम textऔर पसंद है। कॉलम जोड़ने का आपका कोड MySQL पर काम करेगा लेकिन पोस्टग्रैज या ओरेकल या SQL सर्वर पर नहीं।
  • क्या आप वास्तव में डेटा को अच्छी तरह से जोड़ने के लिए ग्राहक पर भरोसा करते हैं ? निश्चित रूप से, ईएवी आदर्श से बहुत दूर है, लेकिन अब आपको कुछ भयावह अस्पष्ट तालिका के नाम मिल गए हैं, जिन्हें आपने डेवलपर को नहीं जोड़ा है, गलत प्रकार के इंडेक्स (यदि कोई हो) के साथ, कोड में कोई बाधा नहीं जोड़ा गया है जहां पर आवश्यकता होती है हो और इतने पर।
  • आपने एप्लिकेशन चलाने वाले उपयोगकर्ता को स्कीमा संशोधन विशेषाधिकार दिए हैं। छोटे बॉबी ड्रॉप टेबल्स संभव नहीं हैं जब आप डीडीएल के बजाय एसक्यूएल तक ही सीमित रहते हैं (सुनिश्चित करें कि आप delete * from studentsइसके बजाय कर सकते हैं , लेकिन आप वास्तव में खराब तरीकों से डेटाबेस को गड़बड़ नहीं कर सकते हैं)। किसी दुर्घटना या दुर्भावनापूर्ण गतिविधि स्काईरॉकेट से स्कीमा एक्सेस के साथ कई चीजें गलत हो सकती हैं।

यह वास्तव में "ऐसा न करने के लिए" उबलता है। यदि आप वास्तव में ऐसा चाहते हैं, तो ईएवी तालिका संरचना के एक ज्ञात पैटर्न या एक डेटाबेस के साथ जाएं जो पूरी तरह से इस संरचना के लिए समर्पित है। किसी तालिका में लोगों को मनमाने क्षेत्र न बनाने दें। सिरदर्द अभी इसके लायक नहीं हैं।


4
आपने डेटाबेस को भी पुनर्निवेशित किया है।
user253751

1
@ मिनीबिस ने इसमें एक परत जोड़ी है जिसमें उपयोगकर्ता बाकी डेटाबेस को प्रबंधित किए बिना या मॉडल को अपडेट करने के लिए रिडाइपिस की आवश्यकता के बिना प्रशासन कर सकता है।

1
@immibis EAV ने वर्षों के लिए रिलेशनल डेटाबेस सर्किल में गर्मागर्म बहस की। सिद्धांत रूप में, यह अनावश्यक है, लेकिन व्यवहार में, आप इसके बिना कुछ चीजें नहीं कर सकते।
रॉस पैटरसन

1
@ShivanDragon जो NoSQL दृष्टिकोण पर जाता है। दस्तावेज़ केवल दस्तावेज़ संग्रहीत करता है और स्कीमा लागू नहीं करता है। जैसे, दस्तावेज़ों को जोड़ना और हटाना और दस्तावेजों को पूरी तरह से डेटाबेस के दायरे से बाहर रखा गया है (और आपने अपने मॉडल को समायोजित करने के लिए लिखा है)। यह संबंधपरक डेटाबेस की तुलना में ईएवी संरचना के लिए समझौता करने का पूरी तरह से अलग सेट है।

1
संबंधित चैट चर्चा: डेटाबेस डिजाइन के विकल्प पर ea

5

यह कुआँ करना कठिन है।

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


सारांश में: थोड़ा परियोजना == KISS। फुर्ती से जमीन पर गिर गया।
एनकेटर

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

0

मैं हाल ही में कुछ इसी तरह से एक क्रॉस आया था।

मैंने 2 टेबल बनाए।

1: table Objects 
    Id , name, type

वह आपकी सभी वस्तुएं हैं। यू सेट का नाम।

और इस वस्तु का एक प्रकार: - मेरे लिए उपलब्ध प्रकार इन्वेंट्री, इन्वेंट्री_इटेम, कार्यालय था।

और सामान्य सेटअप था n आइटम बच्चे या इन्वेंट्री होते हैं जो कार्यालय का बच्चा भी होता है और मैंने वस्तुओं को एक दूसरे से मिलाने के लिए एक जॉइन टेबल का इस्तेमाल किया

2 table settings 
     organization_Id , title, value , type

सेटिंग्स तालिका में उस विशिष्ट ऑब्जेक्ट प्रकार के लिए प्रत्येक फ़ील्ड का नाम, और मूल्य में मान होता है।

कार्यालय के उदाहरण गुण

स्थान, फोन, काम के घंटे

और वस्तुओं के लिए

  • रकम
  • कीमत
  • बारकोड

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

इसलिए जब कभी मुझे एक कार्यालय चाहिए तो मैं इसे अपने सभी संबंधों और सेटिंग्स के साथ आसान लोड करता हूं जहां सेटिंग्स object_I'd (अनुरोधित ऑब्जेक्ट) में होती हैं

उसके बाद मैं सेटिंग्स से सभी पंक्तियों को पिवट करता हूं और यही वह है।

और अगर मैं चाहता था कि एक वस्तु सूची में एक वस्तु के लिए विशिष्ट हो (वैश्विक नहीं) तो मैंने object_I'd = मैं object_objects संबंध तालिका से सेट किया था और मैंने settings.type = relation_setting सेट किया था

मुझे आशा है कि आप समझ गए होंगे कि मेरा क्या मतलब है जब मैं लैपटॉप पाने के लिए पुन: उत्तर देने की कोशिश करूंगा


2
प्रो टिप - अपने फोन से इस मंच पर पोस्ट न करें। स्वतः सुधार आपके पोस्ट के कुछ हिस्सों को अपठनीय बनाता है।
बोबडलिंगिश

Haha अच्छा अवलोकन :)
Zalaboza

0

क्या उपयोगकर्ता परिभाषित क्षेत्रों की अनुमति देने के लिए यह बुरा अभ्यास है?

नहीं, यह बुरा अभ्यास नहीं है। यह काफी सामान्य है। OO के संदर्भ में इसे वंशानुक्रम कहा जाता है। आपके पास एक बेस क्लास इन्वेंट्री है और दो विरासत में मिली कक्षाएं ऑडियोसीडी और फर्नीचर हैं।

आम तौर पर हालांकि, लोग "वास्तविक जीवन" में इस तरह से कुछ कैसे संभालते हैं?

आपको यह तय करना होगा कि इन्वेंट्रीइम, ऑडियोसीडी और फर्नीचर डेटाबेस में कैसे संग्रहीत हैं।

यदि आसान-क्वेरी आपके लिए सबसे महत्वपूर्ण है और db-space / normalization आपके लिए "टेबल-प्रति-पदानुक्रम" स्कीमा को लागू करने से कोई फर्क नहीं पड़ता।

यदि आपके लिए स्थान / सामान्यीकरण सबसे महत्वपूर्ण है और अधिक जटिल प्रश्न आपके लिए "टेबल-प्रति-प्रकार" स्कीमा को लागू करने में कोई समस्या नहीं है।

अधिक जानकारी के लिए डॉटनेट टेबल-प्रति-प्रकार-बनाम-टेबल-प्रति-पदानुक्रम-उत्तराधिकार या जावा हाइबरनेट विरासत देखें


मुझे नहीं पता कि क्या यह सवाल को संबोधित करता है। उपयोगकर्ता नई कक्षाओं को बनाने के लिए कोड को संशोधित नहीं कर रहा है
कॉलिन डी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.