2011-01-16 11 views
17

मैं एक संपादक पर काम कर रहा हूं जो अपने उपयोगकर्ताओं को वास्तविक समय में "ऑब्जेक्ट" परिभाषाएं बनाने में सक्षम बनाता है। एक परिभाषा में शून्य या अधिक गुण हो सकते हैं। एक संपत्ति का नाम एक प्रकार है। एक बार परिभाषा बनने के बाद, कोई उपयोगकर्ता उस परिभाषा का ऑब्जेक्ट बना सकता है और उस ऑब्जेक्ट के प्रॉपर्टी मान सेट कर सकता है।गतिशील गुणों का समर्थन करने के लिए स्कीमा

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

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

पहले, मैं एक मेज है कि मेरे सभी वस्तु परिभाषाओं का आयोजन करेगा की जरूरत है:

Table obj_defs 

id | name  | 
---------------- 
1 | "Bicycle" | 
2 | "Book" | 

तब मैं पकड़े गुण किस तरह प्रत्येक वस्तु परिभाषा होनी चाहिए के लिए एक मेज की जरूरत है:

Table prop_defs 

id | obj_def_id | name  | type | 
------------------------------------ 
1 |   1 | "Size" | ? | 
2 |   1 | "Name" | ? | 
3 |   1 | "Price" | ? | 
4 |   2 | "Title" | ? | 
5 |   2 | "Author" | ? | 
6 |   2 | "ISBN" | ? | 

मैं प्रत्येक ऑब्जेक्ट को रखने वाली तालिका की भी आवश्यकता होगी:

Table objects 

id | created | updated | 
------------------------------ 
1 | 2011-05-14 | 2011-06-15 | 
2 | 2011-05-14 | 2011-06-15 | 
3 | 2011-05-14 | 2011-06-15 | 

अंत में, मुझे एक टेबल चाहिए जो वाई ll प्रत्येक वस्तु के वास्तविक संपत्ति मूल्यों पकड़ है, और एक समाधान इस तालिका इस जैसे प्रत्येक संभव मूल्य प्रकार के लिए एक स्तंभ, के लिए के लिए है: यदि मैं इस स्कीमा लागू किया

Table prop_vals 

id | prop_def_id | object_id | numeric | textual | boolean | 
------------------------------------------------------------ 
1 |   1 |   1 |  27 |   |   | 
2 |   2 |   1 |   | "Trek" |   | 
3 |   3 |   1 | 1249 |   |   | 
4 |   1 |   2 |  26 |   |   | 
5 |   2 |   2 |   | "GT" |   | 
6 |   3 |   2 |  159 |   |   | 
7 |   4 |   3 |   | "It" |   | 
8 |   5 |   3 |   | "King" |   | 
9 |   6 |   4 |  9 |   |   | 

, क्या होगा "प्रकार" prop_defs तालिका के कॉलम को पकड़ो? इंटीग्रेट करता है कि प्रत्येक मानचित्र को कॉलम नाम, वर्चर्स जो कॉलम नाम को पकड़ते हैं? कोई अन्य संभावनाएं? क्या एक संग्रहीत प्रक्रिया मुझे यहां किसी तरह से मदद करेगी? और ऑब्जेक्ट 2 की "नाम" संपत्ति लाने के लिए एसक्यूएल क्या दिखता है?

उत्तर

28

आप एंटीटी-एट्रिब्यूट-वैल्यू मॉडल http://en.wikipedia.org/wiki/Entity-attribute-value_model नामक कुछ को कार्यान्वित कर रहे हैं।

बहुत से लोगों का कहना है कि यह एक बुरा विचार है (आमतौर पर मैं उनमें से एक हूं) क्योंकि आपके अंतिम प्रश्न का उत्तर, "एसक्यूएल लाने के लिए एसक्यूएल क्या होगा ..." "मोटी बालों वाली और गंदा" होती है, और बदतर हो रही है। "

यह आलोचना तब होती है जब आप उपयोगकर्ताओं को अन्य वस्तुओं के अंदर घोंसले की वस्तुओं को शुरू करने की अनुमति देते हैं, यदि आप इसकी अनुमति नहीं देते हैं, तो स्थिति व्यवस्थित रहेगी।

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

क्वेरी हड़पने के लिए एक एकल मूल्य एक मामला बयान करना होगा:

SELECT case when pd.type = "numeric" then pv.numeric 
      when pd.type = "textual" then pv.textual 
      when pd.type = "boolean" then pv.boolean 
    from prov_vals pv 
    JOIN prop_defs pd ON pv.prop_def_id = pv.id 
WHERE pv.object_id = 2 
    AND pd.name = "Name" 
+0

उत्कृष्ट उत्तर! बहुत बहुत धन्यवाद :) –

+2

ईएवी कुछ ऐसी चीजों से बचने के लिए बेहतर होता है जब वस्तुओं को घोंसला करने की ज़रूरत होती है? – ChrisR

+0

अब मोंगोडीबी जैसे नोएसक्यूएल समाधान के साथ, ईएवी अंत में मर सकता है। –

4

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

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

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

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

संबंधित मुद्दे