2010-05-04 12 views
6

अभी मैं अपनी साइट पर फ़िल्टर सिस्टम जोड़ने की योजना बना रहा हूं।एसक्यूएल में फ़िल्टर सिस्टम को कैसे कार्यान्वित करें?

उदाहरण:

(ID=apple, COLOR=red, TASTE=sweet, ORIGIN=US) 
(ID=mango, COLOR=yellow, TASTE=sweet, ORIGIN=MEXICO) 
(ID=banana, COLOR=yellow, TASTE=bitter-sweet, ORIGIN=US) 

तो अब मैं निम्न कार्य में दिलचस्पी है: thisTable से चयन आईडी जहां color = 'पीला' और स्वाद = 'स्वीट'

लेकिन मेरी समस्या मैं कर रहा हूँ है यह मेरी साइट में कई श्रेणियों के लिए कर रहा है, और कॉलम सुसंगत नहीं हैं। (जैसे कि टेबल हैंडफोन के लिए है, तो यह ब्रांड, 3 जी-सक्षम, मूल्य, रंग, वेवलेन्थ, इत्यादि)

मैं एक सामान्य स्कीमा कैसे डिजाइन कर सकता हूं जो इसे अनुमति देता है?

अभी मैं कर रही पर योजना बना रहा हूँ:

table(ID, KEY, VALUE) 

यह स्तंभों की आर्बिटरी संख्या की अनुमति देता है, लेकिन क्वेरी के लिए, मैं मेज से चयन आईडी का उपयोग कर रहा कहां (कुंजी = एक्स 1 और मूल्य = V1) और (कुंजी = एक्स 2 और VALUE = वी 2), .. जो एक खाली सेट देता है।

क्या कोई इस के लिए एक अच्छा समाधान सुझा सकता है? ध्यान दें कि कॉलम की संख्या नियमित रूप से बदल जाएगी

+1

ऐसा नहीं है कि रेडिट ईवा बड़े पैमाने पर उपयोग करता है मेरे आश्चर्य करने के लिए है। http://carsonified.com/blog/dev/steve-huffman-on-lessons-learned-at-reddit/ – crapbag

उत्तर

0

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

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

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

7

entity-attribute-value मॉडल जो आप सुझाते हैं वह इस परिदृश्य में फिट हो सकता है।

फ़िल्टरिंग क्वेरी के संबंध में, आपको यह समझना होगा कि ईएवी मॉडल के साथ आप बहुत सारी क्वेरी पावर का त्याग करेंगे, इसलिए यह काफी मुश्किल हो सकता है। हालांकि यह एक तरीका है अपनी समस्या से निपटने के लिए: इस दृष्टिकोण का

SELECT stuff.id 
FROM  stuff 
JOIN  (SELECT COUNT(*) matches 
      FROM  table 
      WHERE  (`key` = X1 AND `value` = V1) OR 
        (`key` = X2 AND `value` = V2) 
      GROUP BY id 
     ) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id) 
GROUP BY stuff.id; 

एक असजीला सुविधा है जो आपको विशेषता/मान युग्म है कि आप sub_t.matches = 2 में मिलान की उम्मीद की संख्या निर्दिष्ट करने की आवश्यकता है। अगर हमारे पास तीन स्थितियां थीं तो हमें sub_t.matches = 3 निर्दिष्ट करना होगा, और इसी तरह।

के एक टेस्ट केस का निर्माण करते हैं:

CREATE TABLE stuff (`id` varchar(20), `key` varchar(20), `value` varchar(20)); 

INSERT INTO stuff VALUES ('apple', 'color', 'red'); 
INSERT INTO stuff VALUES ('mango', 'color', 'yellow'); 
INSERT INTO stuff VALUES ('banana', 'color', 'yellow'); 

INSERT INTO stuff VALUES ('apple', 'taste', 'sweet'); 
INSERT INTO stuff VALUES ('mango', 'taste', 'sweet'); 
INSERT INTO stuff VALUES ('banana', 'taste', 'bitter-sweet'); 

INSERT INTO stuff VALUES ('apple', 'origin', 'US'); 
INSERT INTO stuff VALUES ('mango', 'origin', 'MEXICO'); 
INSERT INTO stuff VALUES ('banana', 'origin', 'US'); 

क्वेरी:

SELECT stuff.id 
FROM  stuff 
JOIN  (SELECT COUNT(*) matches, id 
      FROM  stuff 
      WHERE  (`key` = 'color' AND `value` = 'yellow') OR 
        (`key` = 'taste' AND `value` = 'sweet') 
      GROUP BY id 
     ) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id) 
GROUP BY stuff.id; 

परिणाम:

+-------+ 
| id | 
+-------+ 
| mango | 
+-------+ 
1 row in set (0.02 sec) 

अब color=yellow और taste=sweet के साथ एक और फल सम्मिलित करते हैं:

INSERT INTO stuff VALUES ('pear', 'color', 'yellow'); 
INSERT INTO stuff VALUES ('pear', 'taste', 'sweet'); 
INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere'); 

समान क्वेरी वापसी होगी:

+-------+ 
| id | 
+-------+ 
| mango | 
| pear | 
+-------+ 
2 rows in set (0.00 sec) 

हम origin=MEXICO साथ संस्थाओं के लिए इस परिणाम को प्रतिबंधित करना चाहते हैं, तो हम एक और OR हालत जोड़ सकते हैं और sub_t.matches = 3 बजाय 2 के लिए जाँच करने के लिए होगा।

SELECT stuff.id 
FROM  stuff 
JOIN  (SELECT COUNT(*) matches, id 
      FROM  stuff 
      WHERE  (`key` = 'color' AND `value` = 'yellow') OR 
        (`key` = 'taste' AND `value` = 'sweet') OR 
        (`key` = 'origin' AND `value` = 'MEXICO') 
      GROUP BY id 
     ) sub_t ON (sub_t.matches = 3 AND sub_t.id = stuff.id) 
GROUP BY stuff.id; 

परिणाम:

जब EAV मॉडल का उपयोग कर
+-------+ 
| id | 
+-------+ 
| mango | 
+-------+ 
1 row in set (0.00 sec) 

हर दृष्टिकोण के रूप में, वहाँ कुछ फायदे और नुकसान हैं। सुनिश्चित करें कि आप अपने आवेदन के संदर्भ में व्यापक रूप से विषय का शोध करें। आप Cassandra, CouchDB, MongoDB, Voldemort, HBase, SimpleDB या अन्य प्रमुख-मूल्य वाले स्टोर जैसे वैकल्पिक संबंधपरक डेटाबेस पर भी विचार करना चाहेंगे।

+0

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

+0

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

0

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

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

यह एक महंगा समस्या है चाहे आप इसे कैसे फिसलते हैं। क्या आप अब विकास के समय के साथ भुगतान करना चाहते हैं या बाद में भुगतान करना चाहते हैं जब आपका प्रदर्शन टैंक? (। गलत जवाब "बाद में भुगतान करें" है)

+0

क्या आप एक टेबल डिज़ाइन की अनुशंसा कर सकते हैं जो आपके उत्तर को फिट करे? मैं वास्तव में समझ में नहीं आता कि आप क्या कह रहे हैं। – crapbag

+0

मैं उस सिद्धांत के नाम पर आया जिस पर मैं संकेत दे रहा था: एंकर मॉडलिंग। स्रोत थोड़ा अकादमिक है: http://syslab.dsv.su.se/profiles/blogs/anchor-modeling ताकि आपको यह स्पष्टीकरण पचाने में थोड़ा आसान लगे: http://askmonty.org/wiki/Manual: Table_Elimination प्रक्रियात्मक डेटाबेस अनुवाद (ओआरएम या रिवर्स ओआरएम तकनीक) का (संबंधित लेकिन अलग) बिंदु एक जटिल, विशिष्ट डेटा संरचना तक पहुंचने के लिए आपके द्वारा लिखे गए कोड की मात्रा को कम करना है जिसमें बेहतर प्रदर्शन, सामान्यीकरण और संबंधपरकता है विशेषताओं। – cbednarski

1

मेरे लिए काम किया है:

SELECT * FROM mytable t WHERE 
    t.key = "key" AND t.value = "value" OR 
    t.key = "key" AND t.value = "value" OR 
    .... 
    t.key = "key" AND t.value = "value" 
GROUP BY t.id having count(*)=3; 

गिनती (*) = 3 की

t.key राशि से मेल खाना चाहिए = " कुंजी "और t.value =" का मान "

मामलों

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