Mysql में सबसे अच्छा पड़ोसी खोज कैसे लागू करें?


10

तो, संक्षेप में,

  1. अक्षांश और देशांतर का डेटा प्रकार क्या होना चाहिए?
  2. उदाहरण के लिए पहले 100 निकटतम रेस्तरां पाने के लिए मुझे किस एसक्यूएल कमांड को कॉल करना चाहिए?

विवरण:

मेरे पास अक्षांश और देशांतर के साथ 100k biz रिकॉर्ड है। मैं देखता हूं कि MySQL वास्तव में बिंदु नामक डेटा प्रकार का समर्थन करता है। क्या मुझे इसके बजाय उपयोग करना चाहिए?

क्या MySQL समर्थन KDTree भंडारण प्रणाली http://en.wikipedia.org/wiki/File:KDTree-animation.gif

क्या अक्षांश और देशांतर को संग्रहीत करने के लिए नियमित फ्लोट डेटा प्रकार के बजाय बिंदु डेटा प्रकार का उपयोग करना सबसे अच्छा है?

आखिरकार मैं उदाहरण के लिए 105,6 अंक के निकटतम प्रथम 100 रेस्तरां जैसी चीजों को खोजना चाहता हूं और मेरे डेटाबेस में बहुत सारे बिज़ और अंक हैं। स्पष्ट रूप से हर रिकॉर्ड के लिए एक-एक दूरी तय करना और हर बिंदु के लिए O (n) होगा और इसलिए बेकार है।

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

हालांकि, मुझे लगता है कि फसल के जवाब का एक ही चरम है जो कि सही होना चाहिए? वास्तव में, अक्षांश और देशांतर के आधार पर भंडारण का स्थान और इसके नज़दीक सामान ढूंढना एक बहुत ही आम समस्या है, मुझे उम्मीद है कि mysql के लिए एक विशेष डिज़ाइन पैटर्न होना चाहिए। क्या यह ऐसा है?

मैं इसके बारे में और कहाँ जान सकता हूँ? धन्यवाद।



ऐसा लगता है कि यहाँ समाधान dba.stackexchange.com/questions/4210/… सबसे अच्छा समाधान है। मेरा मतलब है कि इस बात को MYSQL स्थानिक कहा जाता है। हालाँकि आप ऐसी चीज़ों को बाहर नहीं निकाल सकते जहाँ (दूरी (x) <20)। यह अभी तक लागू नहीं हुआ है।
user4951

जवाबों:


11

जहां तक ​​डिजाइन पैटर्न की बात है, तो येल्प का प्रश्न काफी मानक सामान है।

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

उनकी स्लाइड से:

set @orig_lat=122.4058; set @orig_lon=37.7907;
set @dist=10;

SELECT *, 3956 * 2 * ASIN(SQRT(
POWER(SIN((@orig_lat - abs(dest.lat)) * pi()/180 / 2), 2) +  COS(@orig_lat * pi()/180 ) * COS(abs(dest.lat) * pi()/180) *  POWER(SIN((@orig_lon  dest.lon) * pi()/180 / 2), 2) )) as  distance
FROM hotels dest 
having distance < @dist
ORDER BY distance limit 10

स्टैक ओवरफ्लो पर भू-स्थानिक दूरी के बारे में अधिक लंबा, अधिक गहन उत्तर है ।

लेकिन आप अभी भी अक्षांश और देशांतर द्वारा परिणामों को सीमित करना चाहते हैं।

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

एक अंतिम लिंक: आप स्थानिक अनुक्रमित का उपयोग करके प्रश्नों को गति देने के बारे में इस SO थ्रेड की जांच करना चाह सकते हैं ।


[क्वेरी 4 में त्रुटि] आपके SQL सिंटैक्स में एक त्रुटि है; उस मैनुअल की जाँच करें जो आपके MySQL सर्वर वर्जन से मेल खाता है, जो '- dest.lon) * pi () / 180 (2/2), 2))) से दूरी के रूप में उपयोग करने के लिए लाइन से नेटवर्क_पॉस डिस्ट' d 'लाइन 2 पर हो
फेलिप

नमस्ते, @dist मिल्स पर है? धन्यवाद
जॉर्ज ओलाफ एरलैंडन

1
@ ओलाफ्रालैंड्सन हाँ यह मील में है
Jan van der Vegt

4

बिंदु डेटाटाइप्स ठीक हैं; आप केवल लाट / लोन मान प्राप्त करने के लिए X (निर्देशांक) / Y (निर्देशांक) लागू कर सकते हैं।

उदाहरण के लिए:

SELECT id, 
(3959 
    * acos(
        cos(radians(37)) 
        * cos(radians(Y(coord)))
        * cos(radians(X(coord)) - radians(-122)) 
        + sin(radians(37))
        * sin(radians(Y(coord)))
      )
) AS distance 
FROM markers HAVING distance < 25 
ORDER BY distance LIMIT 20;

37 अव्यक्त है और -122 अकेला है? और 25 मीटर या किमी है?
फेलिप

1

में देखें कुशल कोड: 100 रेस्तरां कुछ समन्वय करने के लिए निकटतम खोजें http://mysql.rjweb.org/doc.php/latlng यह कंप्यूटिंग "महान cirle" दूरी के लिए एक संग्रहीत समारोह भी शामिल है।

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