कॉन्फ़िगरेशन डेटा: एकल-पंक्ति तालिका बनाम नाम-मूल्य-जोड़ी तालिका


64

मान लीजिए कि आप एक एप्लिकेशन लिखते हैं जिसे उपयोगकर्ता द्वारा कॉन्फ़िगर किया जा सकता है। इस "कॉन्फ़िगरेशन डेटा" को डेटाबेस में संग्रहीत करने के लिए, दो पैटर्न आमतौर पर उपयोग किए जाते हैं।

  1. एकल पंक्ति तालिका

      CompanyName  |  StartFullScreen  |  RefreshSeconds  |  ...
    ---------------+-------------------+------------------+--------
      ACME Inc.    |        true       |       20         |  ...
    
  2. नाम-मान-जोड़ी टेबल

      ConfigOption   |   Value
    -----------------+-------------
     CompanyName     | ACME Inc.
     StartFullScreen | true (or 1, or Y, ...)
     RefreshSeconds  | 20
     ...             | ...
    

मैंने दोनों विकल्प जंगली में देखे हैं, और दोनों के स्पष्ट लाभ और नुकसान हैं, उदाहरण के लिए:

  • एकल-पंक्ति तालिका आपके पास होने वाले कॉन्फ़िगरेशन विकल्पों की संख्या को सीमित करती है (क्योंकि एक पंक्ति में कॉलम की संख्या आमतौर पर सीमित होती है)। हर अतिरिक्त कॉन्फ़िगरेशन विकल्प के लिए DB स्कीमा परिवर्तन की आवश्यकता होती है।
  • एक नाम-मूल्य-जोड़ी तालिका में सब कुछ "कड़ाई से टाइप" है (आपको अपने बूलियन / दिनांक / आदि मापदंडों को एनकोड / डिकोड करना होगा)।
  • (बहुत अधिक)

क्या विकास समुदाय के भीतर कुछ सहमति है जिसके बारे में विकल्प बेहतर है?


2
कोई कारण नहीं है कि 'वर्टिकल' एप्रोच कैंट में अलग-अलग तरह के डेटा होते हैं। पंक्ति में एक इंट, फ्लोट और टेक्स्ट कॉलम जोड़ें। 'SaveConfigInt (' फ़ील्ड ', n) जैसे प्रकार-विशिष्ट कार्यों का उपयोग करके इससे मूल्यों को सहेजें / लोड करें
ग्रैंडमास्टरबी

4
इस बारे में एक उत्कृष्ट StackOverflow प्रश्न है, और शीर्ष उत्तर दोनों दृष्टिकोणों के लिए पेशेवरों और विपक्षों को देता है। stackoverflow.com/questions/2300356/…
केविन

1
दृष्टिकोण 3: JSON या YAML जैसे साधारण डेटा इंटरचेंज फॉर्मेट के साथ सिंगल कॉलम / सिंगल रो। दोनों दृष्टिकोणों से लाभ मिलाता है।
श्लोमर

xml / json जैसे जटिल डेटा वाली एकल-पंक्ति तालिका का उपयोग करने के बारे में क्या है <<>> CompanyName> ACME Inc। </ CompanyName> <StartFullScreen> true </ StartFullScreen> 20 <RefreshSeconds> </ RefreshSeconds> </ config> और>। व्यापार परत में मान्य वस्तु?
जॉन

1
@ जॉन: अच्छा विचार, अगर पदानुक्रमित संरचनाओं की आवश्यकता है। यदि वे नहीं हैं, तो यह केवल जोड़ा जटिलता के साथ 2 विकल्प है।
हेनजी

जवाबों:


15

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

तो क्या आप कक्षा के सदस्यों पर एक शब्दकोश / मानचित्र का उपयोग करेंगे? शायद तब तक नहीं जब तक आपके पास यह सोचने का कारण न हो कि डेटा की मात्रा पूरी तरह से अनुकूल है, नाम-पेयर जोड़ी तालिका की तरह।


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

1
@devanalyst नहीं, यदि डेटा घटक से घटक में बदल सकता है, तो इसका प्रतिनिधित्व करने के लिए एक स्थिर तालिका बनाने के प्रयास का कोई मतलब नहीं होगा। उस स्थिति में दूसरे विकल्प का उपयोग करना बेहतर होगा।
नील

12

मैं आमतौर पर विकल्प 2 के साथ जाता हूं लेकिन मेरे पास डेटा प्रकार लागू करने के लिए कई कॉलम होंगे

ConfigOption   |   textValue    |   DateValue   |   NumericValue

विकल्प 1 में अतिरिक्त लाभ है कि आप बहुत आसानी से एक Activeकॉलम जोड़कर पूरे विन्यास को "स्वैप" कर सकते हैं ।


यदि आप कॉन्फ़िगरेशन को अक्षम करने की अनुमति देने जा रहे हैं (विकल्प 1 के लिए), तो कम से कम इसे activatedOnटाइमस्टैम्प बनाएं , इसलिए आप बता सकते हैं कि यह कब सक्रिय हुआ था। और अगर आप विकल्प 2 के साथ जा रहे हैं ... क्या होगा यदि अंत कई कॉलमों में मूल्यों को संग्रहीत करता है (या यह ओरेकल है, जहां (जाहिरा तौर पर) अशक्त और एक खाली स्ट्रिंग समतुल्य है)?
क्लॉकवर्क-म्यूजियम

1
@ X-Zero, मल्टीपल कन्फिग्स को स्टोर करने का काम आमतौर पर टेस्टिंग उद्देश्यों के लिए किया जाता है, लेकिन एक टाइम स्टैम्प कैंट को चोट पहुंचती है। विन्यास अनुरक्षण, मान प्राप्त करने के लिए कॉल करने से पता चलेगा कि किस कॉलम को जांचना है, यदि आप वास्तव में चाहते हैं, तो आप डेटा प्रकार के लिए एक कॉलम जोड़ सकते हैं .. लेकिन मुझे लगता है कि खत्म हो गया है ...
Morons

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

5
प्रत्येक विकल्प 1 को सॉफ्टवेयर में लागू किया गया है जो मैंने देखा है, इसे विकल्प 2 में बदलना होगा। विकल्प 2 समय के साथ बनाए रखना आसान है, बस पहली बार सही ढंग से लागू करने के लिए एक स्पर्श अधिक समय लगता है। विकल्प 1 त्वरित और लागू करना आसान है लेकिन समय के साथ रखरखाव भयानक है जब तक कि आपका सॉफ्टवेयर बढ़ने की कोई संभावना नहीं है।
जिमी हॉफ

8

मेरे लिए, चाहे आप एकल-पंक्ति में जाएं या ईएवी इस बात पर निर्भर करता है कि आप उनका उपभोग कैसे करना चाहते हैं।

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

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

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

मुख्य नुकसान यह है कि प्रत्येक नए मूल्य के लिए एक संरचनात्मक परिवर्तन आवश्यक है; नए DB कॉलम, DAL में नया कॉलम (या तो मैपिंग या SQL क्वेरीज़ / SPs), नया डोमेन कॉलम, सभी को ठीक से उपयोग करने के लिए आवश्यक है।

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

संक्षेप में, विन्यास को स्टोर करने के लिए एक ईएवी स्कीमा वास्तव में उस समस्या को हल नहीं करता है जो इसे हल करने के लिए करता है, और अधिकांश वर्कआर्ड्स उन समस्याओं को हल करता है जो DRY का उल्लंघन करता है।


3

विशेष रूप से कॉन्फ़िगरेशन मानों के लिए, मैं कहूंगा - सिंगल रो के साथ जाएं। जब तक आप वर्तमान में विकास से नहीं गुजर रहे होते हैं, तब तक वे कॉलम कितनी बार बदलने वाले हैं?

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

इसके अतिरिक्त, आपने कहा कि "उपयोगकर्ता" बिना टोपी दिए, इन विकल्पों को कॉन्फ़िगर कर सकते हैं। क्या वे प्रति-उपयोगकर्ता कॉन्फ़िगरेशन हैं? यदि हां, तो मैं और भी दृढ़ता से तर्क दूंगा कि कॉन्फ़िगरेशन विकल्प कॉलम में होना चाहिए - प्रति उपयोगकर्ता एक पंक्ति। यह बहुत बाद में रखरखाव के सिरदर्द को बचाएगा।


2

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

यदि आपके क्लाइंट JSON टुकड़े को संसाधित नहीं कर सकते हैं, तो नए ग्राहक प्राप्त करें।


1

एकल पंक्ति पेशेवरों: अच्छी तरह से परिभाषित। विपक्ष: कॉन्फ़िगरेशन बदलने से दर्द हो सकता है। DB पलायन आदि।

इकाई-मूल्य पेशेवरों: सुपर लचीला, अपने विन्यास को विकसित करने का समर्थन करता है। विपक्ष: प्रासंगिक अखंडता? आपके कोड में अधिक चेक यह देखने के लिए कि क्या संपत्ति मौजूद है इससे पहले कि आप उस पर कुछ भी कर सकें।

मैं मानगो जैसे गैर-संबंधपरक डीबी द्वारा समर्थित दृष्टिकोण 2 को ले जाऊंगा। अगर कोई ऐसी चीज है जिस पर आप यकीन कर सकते हैं, तो उसका बदलाव।


1

दोनों का उपयोग करें!

सॉर्ट करें कि क्या विकल्प कई उदाहरण हो सकते हैं, और क्या विकल्प सामान्य हैं।

एकल-पंक्ति तालिका (कॉन्फ़िगरेशन)

  id  |  company_name  |  start_fullscreen  |  refresh_seconds  |  ...
------+----------------+--------------------+-------------------+-------
  4   |  ACME Inc.     |  true              |  20               |  ...

नाम-मूल्य-जोड़ी तालिका (विकल्प)

  name             |  value          | update_time  
-------------------+-----------------+--------------
  generic_option_1 |  Option 1 Value | timestamp    
  generic_option_2 |  Option 2 Value | timestamp    
  generic_option_3 |  Option 3 Value | timestamp    
  configuration    |  4              | timestamp    
  ...              |  ...            | ...          

मुझे लगता है कि यह अधिक लचीला है।

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