क्या मुख्य मूल्यों के इस डेटाबेस स्कीमा का कोई नाम है?


68

हम एक ग्राहक से एक रूटीन डेटा फीड की प्रक्रिया करते हैं, जो अपने डेटाबेस को एक ऐसे फॉर्म से हटाता है जो परिचित लगता है (एक पंक्ति प्रति इकाई, एक कॉलम प्रति विशेषता) जो मुझे अपरिचित लगता है (एक पंक्ति प्रति इकाई प्रति विशेषता):

पहले: प्रति विशेषता एक कॉलम

ID   Ht_cm   wt_kg   Age_yr  ... 
1      190      82     43    ...
2      170      60     22    ...
3      205      90     51    ...

के बाद: सभी विशेषताओं के लिए एक कॉलम

ID    Metric   Value
 1     Ht_cm     190
 1     Wt_kg     82
 1     Age_yr    43
 1      ...
 2     Ht_cm     170
 2     Wt_kg     60
 2     Age_yr    22
 2     ...
 3     Ht_cm     205
 3     Wt_kg     90
 3     Age_yr    51
 3     ...

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

जवाबों:


91

इसे एंटिटी-एट्रीब्यूट-वैल्यू (कभी-कभी 'नाम-वैल्यू पेयर' भी कहा जाता है) और "जब एक रिलेशनल डेटाबेस में ईएवी पैटर्न का उपयोग लोग करते हैं तो यह" स्क्वायर छेद में एक गोल खूंटी "का एक क्लासिक मामला है।

यहां बताया गया है कि आपको ईएवी का उपयोग क्यों नहीं करना चाहिए :

  • आप डेटा प्रकारों का उपयोग नहीं कर सकते। इससे कोई फर्क नहीं पड़ता कि मूल्य एक दिनांक, संख्या या धन (दशमलव) है। यह हमेशा varchar के लिए coerced होने जा रहा है। यह मामूली प्रदर्शन समस्या से लेकर बड़े आंत-दर्द तक हो सकता है (कभी-कभी मासिक रोल-अप रिपोर्ट में एक प्रतिशत भिन्नता का पीछा करना पड़ा?)।
  • आप (आसानी से) बाधाओं को लागू नहीं कर सकते। इसके लिए "सभी को 0 और 3 मीटर के बीच की ऊँचाई चाहिए" या "आयु शून्य और> = 0" नहीं होनी चाहिए, 1-2 पंक्तियों का विरोध करने के लिए कोड की एक हास्यास्पद मात्रा की आवश्यकता होती है। एक अच्छी तरह से मॉडलिंग प्रणाली में।
  • ऊपर से संबंधित, आप आसानी से यह गारंटी नहीं दे सकते कि आपको प्रत्येक ग्राहक के लिए आवश्यक जानकारी मिल जाएगी (उम्र एक से गायब हो सकती है, फिर अगला उनकी ऊंचाई आदि को याद कर सकता है)। आप इसे कर सकते हैं, लेकिन यह एक बहुत अधिक कठिन की तुलना में एक नरक है SELECT height, weight, age FROM Client where height is null or weight is null
  • संबंधित फिर से, डुप्लिकेट डेटा का पता लगाने के लिए बहुत मुश्किल है (क्या होता है अगर वे आपको एक ग्राहक के लिए दो उम्र देते हैं? डेटा को नीचे दे रहे हैं, जैसा कि नीचे है, तो आपको परिणाम की दो पंक्तियाँ देगा यदि आपके पास एक विशेषता दोगुनी है। यदि एक ग्राहक है। दो विशेषताओं के लिए दो अलग-अलग प्रविष्टियाँ हैं, आपको नीचे दी गई क्वेरी से चार पंक्तियाँ मिलेंगी )।
  • आप यह भी गारंटी नहीं दे सकते कि विशेषता नाम सुसंगत हैं। "Age_yr" "AGE_IN_YEARS" या "आयु" बन सकता है। (आमतौर पर यह एक समस्या से कम है जब आप एक अर्क प्राप्त कर रहे हैं जब लोग डेटा डाल रहे हैं, लेकिन फिर भी।)
  • किसी भी प्रकार की nontrivial क्वेरी एक पूर्ण आपदा है। तीन-विशेषता ईएवी प्रणाली को युक्तिसंगत बनाने के लिए आप इसे तर्कसंगत तरीके से क्वेरी कर सकते हैं इसके लिए ईएवी तालिका के तीन जोड़ों की आवश्यकता होती है।

की तुलना करें:

SELECT cID.ID AS [ID], cH.Value AS [Height], cW.Value AS [Weight], cA.Value AS [Age]
FROM (SELECT DISTINCT ID FROM Client) cID 
      LEFT OUTER JOIN 
    Client cW ON cID.ID = cW.ID AND cW.Metric = "Wt_kg" 
      LEFT OUTER JOIN 
    Client cH ON cID.ID = cH.ID AND cW.Metric = "Ht_cm" 
      LEFT OUTER JOIN 
    Client cA ON cID.ID = cA.ID AND cW.Metric = "Age_yr"

सेवा:

SELECT c.ID, c.Ht_cm, c.Wt_kg, c.Age_yr
FROM Client c

यहां आपको EAV का उपयोग करने की एक (बहुत छोटी) सूची दी गई है:

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

मैं जानता हूँ कि मैं सिर्फ का ब्यौरा इस पूरे पोस्ट खर्च क्यों EAV ज्यादातर मामलों में एक भयानक विचार है - लेकिन वहाँ हैं कुछ मामलों में जहां यह आवश्यक है / अपरिहार्य। हालाँकि, अधिकांश समय (ऊपर दिए गए उदाहरण सहित), इसके लायक होने की तुलना में कहीं अधिक परेशानी होने वाली है। यदि आपके पास ईएवी-टाइप डेटा इनपुट के व्यापक समर्थन की आवश्यकता है, तो आपको उन्हें एक कुंजी-मूल्य प्रणाली में संग्रहीत करना चाहिए, जैसे कि Hadoop / HBase, CouchDB, MongoDB, Cassandra, BerkeleyDB।


7
एक मामूली सूचना के साथ +1: आप डेटा प्रकारों का उपयोग कर सकते हैं यदि आप विभिन्न प्रकारों के मूल्यों को अलग-अलग तालिकाओं में डालते हैं (अच्छी तरह से, क्लासिक ईएवी नहीं, लेकिन सुधार की तरह)। (लेकिन फिर एक अतिरिक्त प्रश्न आता है: आप एक नई विशेषता के प्रकार को कैसे जानते हैं?)
dezso

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

10
@JoelBrown आप अब परवाह नहीं करते हैं, लेकिन अगर सड़क के नीचे एक वीपी यह जानने के लिए कहता है कि कैटलॉग में कितने शर्ट में ब्राउन बटन और बटन डाउन कॉलर दोनों हैं, यह लिखने के लिए एक प्रश्न की एक कुतिया होगी। ईएवी अपने आप में आमतौर पर योजना या दूरदर्शिता की कमी को दर्शाता है।
JNK

2
@JoelBrown मैं असहमत नहीं हूं कि इसका (बहुत छोटा बहुत संकीर्ण) उपयोग है। लेकिन अगर जानकारी किसी भी संरचित फैशन में कभी भी संभव हो सकती है, तो यह संभवतः ईएवी में नहीं होना चाहिए
जेएनके

4
@JoelBrown यदि आपकी व्यावसायिक आवश्यकताएं या डेटा आप परिवर्तनों को संग्रहीत कर रहे हैं, तो आपका डेटा मॉडल होना चाहिए । आपके डेटा मॉडल को पत्थर में नहीं तराशा जाना चाहिए। इसके अलावा, एक रिलेशनल डेटाबेस के लिए, 99% लोग ईएवी का उपयोग अपने तर्क फोड़े का उपयोग करते हैं "मैं अपने डेटा को स्टोर करने के बारे में सोचने में समय व्यतीत नहीं करना चाहता हूं" बजाय सभी डेटाबेस पैटर्न और मॉडल को ध्यान में रखते हुए, जिन्हें मैं जानता हूं, EAV इस डेटा सेट के लिए सबसे अच्छा काम करता है ”। दोहराने के लिए - वहाँ रहे हैं मामलों में जहां EAV उपयोगी (और शायद 'सही' जवाब) है, लेकिन वे कुछ और दूर के बीच कर रहे हैं।
साइमन रिगार्ट्स

18

इकाई विशेषता मूल्य (EAV)

यह मेरे सहित कई लोगों द्वारा एक प्रतिमान माना जाता है।

यहाँ आपके विकल्प हैं:

  1. डेटाबेस तालिका विरासत का उपयोग करें

  2. XML डेटा और SQLXML फ़ंक्शन का उपयोग करें

  3. HBase की तरह एक nosql डेटाबेस का उपयोग करें


3
निश्चित रूप से अधिकांश उपयोग के मामलों के लिए एक विरोधी पैटर्न। यदि आपके पास वास्तव में छोटा डेटा सेट है और प्रदर्शन मायने नहीं रखता है तो यह आपके लिए काम कर सकता है।
JNK

16

PostgreSQL में, ईएवी संरचनाओं से निपटने का एक बहुत अच्छा तरीका अतिरिक्त मॉड्यूल है hstore, जो संस्करण 8.4 या बाद के संस्करण के लिए उपलब्ध है। मैं मैनुअल को उद्धृत करता हूं:

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

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

9.4 प्रेषित करता है ( jsonbविकल्पों में से सूची में "बड़े पैमाने पर श्रेष्ठ!" "बाइनरी JSON" डेटा प्रकार । उन्नत सूचकांक विकल्पों के साथ।


10

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

@ साइमन का जवाब पहले से ही दिखाता है कि कई जोड़ का उपयोग करके एक क्वेरी कैसे करें।

नमूना डेटा का इस्तेमाल किया:

CREATE TABLE yourtable ([ID] int, [Metric] varchar(6), [Value] int);

INSERT INTO yourtable ([ID], [Metric], [Value])
VALUES (1, 'Ht_cm', 190),
    (1, 'Wt_kg', 82),
    (1, 'Age_yr', 43),
    (2, 'Ht_cm', 170),
    (2, 'Wt_kg', 60),
    (2, 'Age_yr', 22),
    (3, 'Ht_cm', 205),
    (3, 'Wt_kg', 90),
    (3, 'Age_yr', 51);

यदि आप एक RDBMS का उपयोग कर रहे हैं जिसमें एक PIVOTफ़ंक्शन है ( SQL Server 2005+ / Oracle 11g + ) तो आप डेटा को निम्न तरीके से क्वेरी कर सकते हैं:

select id, Ht_cm, Wt_kg, Age_yr
from
(
  select id, metric, value
  from yourtable
) src
pivot
(
  max(value)
  for metric in (Ht_cm, Wt_kg, Age_yr)
) piv;

SQL फिडेल को डेमो के साथ देखें

यदि आपके पास किसी PIVOTफ़ंक्शन तक पहुंच नहीं है , तो आप CASEडेटा को वापस करने के लिए एक कथन के साथ एक कुल फ़ंक्शन का उपयोग कर सकते हैं :

select id,
  max(case when metric ='Ht_cm' then value else null end) Ht_cm,
  max(case when metric ='Wt_kg' then value else null end) Wt_kg,
  max(case when metric ='Age_yr' then value else null end) Age_yr
from yourtable
group by id

SQL फिडेल को डेमो के साथ देखें

इन दोनों प्रश्नों के परिणाम में डेटा वापस आ जाएगा:

| ID | HT_CM | WT_KG | AGE_YR |
-------------------------------
|  1 |   190 |    82 |     43 |
|  2 |   170 |    60 |     22 |
|  3 |   205 |    90 |     51 |

10

यह देखने के लिए कि ईएवी डीबी मॉडल की आलोचना कैसे की जाती है और यहां तक ​​कि कुछ लोगों द्वारा "विरोधी पैटर्न" के रूप में माना जाता है।

जहाँ तक मेरा सवाल है, प्रमुख डाउनसाइड्स हैं:

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

हालाँकि, आपको निश्चित रूप से इस समाधान को नहीं छोड़ना चाहिए, और यहाँ है क्यों:

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

2
लर्निंग कर्व पहले ईएवी डिजाइन के एक मुकाबले के लिए स्थिर है। उसके बाद सभी एक जैसे दिखते हैं।
ypercube y

1
अस्थायी टिप्पणी: मुझे समझ में नहीं आता कि "रिपोर्टिंग के लिए अनुकूल नहीं" दावा क्यों। ईएवी रिपोर्टिंग के लिए बहुत अच्छा लगता है। Eav.values ​​से ObjectId का चयन करें जहाँ गुण = d नाम और मान 'm%' है। वर्चुअल स्कीमा में परिवर्तन (जैसे गुण जोड़ना) को पुन: स् थान किए बिना किसी भी डायनामिक रिपोर्टिंग इंटरफेस (जैसे ड्रॉपडाउन) में शामिल किया जा सकता है।
क्रुकसेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.