2011-07-24 14 views
5

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

SELECT *, SQRT(POW((a < min_a)*(min_a - a) + (a > max_a)*(a - max_a), 2) + 
       POW((b < min_b)*(min_b - b) + (b > max_b)*(b - max_b), 2) + 
       ...) AS match 
WHERE a < (min_a - max_allowable_deviation) AND a > (max_a + max_allowable_deviation) AND ... 
ORDER BY match ASC 

जहां ए और बी वस्तु और min_a, max_a, min_b और max_b के गुण हैं उपयोगकर्ता निर्धारित मान रहे हैं:

फिलहाल मैं निम्न क्वेरी का उपयोग कर MySQL में यह लागू किया। असल में मिलान वांछित सीमा और विशेषता के वास्तविक मूल्य के बीच वर्ग अंतर के योग की वर्ग जड़ है। 0 का मान एक सही मिलान का अर्थ है।

तालिका में कुछ मिलियन रिकॉर्ड हैं और WHERE क्लॉजूल केवल गणना के रिकॉर्ड की संख्या को सीमित करने के लिए पेश किया गया है। एक सूचकांक सभी पूछताछ रिकॉर्ड पर रखा गया है और क्वेरी 500ms की तरह लेती है। मैं इस नंबर को बेहतर बनाना चाहता हूं और मैं इस क्वेरी को बेहतर बनाने के तरीकों की तलाश में हूं।

इसके अलावा मैं सोच रहा हूं कि इस काम को करने के लिए एक अलग डेटाबेस बेहतर अनुकूल होगा या नहीं। इसके अलावा मैं अपने लचीले डेटा स्कीम विकल्पों के कारण, नोएसक्यूएल डेटाबेस में बदलना चाहता हूं। मैं MongoDB में देख रहा हूं, लेकिन इस समस्या को कुशलतापूर्वक (तेज़) हल करने का कोई तरीका नहीं मिला।

क्या कोई डेटाबेस MySQL से इस नौकरी के लिए बेहतर अनुकूल है?

+0

मैं याद कर रहा हूँ, जहाँ आप वास्तव में एक समस्या है - इस समय से पहले अनुकूलन की तरह लगता है ... –

+0

आप एसक्यूएल सर्वर समीक्षा कर सकते हैं या ओरेकल की विचारों को इंडेक्स करने की क्षमता। एक दृश्य बनाएं जो पंक्तियों और उनके मैचों का वर्णन करता है और उन्हें अनुक्रमित करता है। –

+0

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

उत्तर

4

R-trees पर एक नज़र डालें। (विशिष्ट रूपों पर पृष्ठ बहुत अधिक विस्तार और वर्तमान छद्म कोड में जाते हैं)। ये डेटा संरचनाएं आपको बाध्य आयताकार से पूछताछ करने की अनुमति देती हैं, जो कि प्रत्येक विशेषता पर श्रेणियों द्वारा खोज की आपकी समस्या है।

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

इसके अलावा, यह C++ header file आर-पेड़ को कार्यान्वित करने वाला है, लेकिन वर्तमान में यह केवल इन-मेमोरी संरचना है। यद्यपि यदि आपका डेटा सेट केवल कुछ मिलियन पंक्तियां है, तो स्टार्टअप पर बस इस मेमोरी स्ट्रक्चर को लोड करने के लिए व्यवहार्य लगता है और जब भी नई कारें जोड़ दी जाती हैं तो अपडेट करें (जो मुझे लगता है कि कम है)।

+0

+1 एन-आयामी डेटा का समर्थन करने वाला एक स्थानिक डेटाबेस ऐसे प्रश्नों के लिए विस्तृत समाधान होगा। @Ewout: पोस्टग्रेज़ भी देखें: http://www.postgresql.org/docs/9.0/interactive/gist-intro.html –

+0

@ कुई तांग: धन्यवाद! मैंने पहले आर-पेड़ों के बारे में कभी नहीं सुना था, लेकिन यह मेरी समस्या का बिल्कुल वर्णन कर रहा है। यह एक शर्म की बात है कि बहुआयामी स्थानिक इंडेक्स के लिए डिफ़ॉल्ट समर्थन के साथ डेटाबेस मौजूद नहीं है। –

2

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

माइस्क्ल टेक्स्ट-आधारित खोज प्रदान करने के लिए एक प्लगइन प्रदान करता है, लेकिन मैं इसे अलग से उपयोग करना पसंद करता हूं, इस तरह यह आसानी से मापनीय होता है (केवल पढ़ने के लिए, आपके पास एकाधिक ल्यूसीन इंजन हो सकते हैं), और आसानी से प्रबंधित किया जा सकता है।

Solr भी देखें, जो ल्यूसीन के शीर्ष पर बैठता है और आपको सरल जावा ऑब्जेक्ट (सूचियां, सरणी इत्यादि) को स्टोर करने, पुनर्प्राप्त करने और खोजने की अनुमति देता है।

+0

ओपी पूरी पाठ खोज के लिए नहीं पूछ रहा है। इसके बजाय, वह सीमा से अलग संख्यात्मक क्षेत्रों से पूछना चाहता है। –

+0

ओपी के शब्दों में: * क्या कोई डेटाबेस इस काम के लिए MySQL से बेहतर अनुकूल है? * – Bohemian

+0

@ बोहेमियन: उत्तर के लिए धन्यवाद! मैं वास्तव में नहीं देखता कि ल्यूसीन जैसे टेक्स्ट सर्च इंजन कैसे मेरी मदद करेंगे। यह मेरी समझ है कि ल्यूसीन संख्यात्मक मूल्यों पर प्रश्न करने के लिए वास्तव में उपयुक्त नहीं है। क्या मुझे लुसीन की कुछ विशेषता याद आ रही है? –

1

संभावना है कि आपकी अनुक्रमणिका बहुत मदद नहीं कर रही है, और मैं एक और डेटाबेस तकनीक के बारे में सोच नहीं सकता जो काफी बेहतर होगा। MySQL के साथ प्रयास करने के लिए कुछ चीजें ....

मैं स्मृति तालिका में डेटा की एक प्रति डालने का प्रयास करता हूं। कम से कम टेबल स्कैन स्मृति में होंगे .... http://dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html

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

http://dev.mysql.com/doc/refman/5.0/en/adding-functions.html

+0

आपके उत्तर के लिए धन्यवाद! मैं पहले से ही एक मेमोरी टेबल के बारे में सोच रहा था। उपयोगकर्ता परिभाषित समारोह भी एक अच्छा सुझाव है। मैं उनको देखूंगा। –

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