Làm thế nào để thực hiện tốt nhất tìm kiếm hàng xóm gần nhất trong mysql?


10

Vì vậy, trong ngắn hạn,

  1. Kiểu dữ liệu của vĩ độ và kinh độ là gì?
  2. Lệnh SQL nào tôi nên gọi để lấy 100 nhà hàng gần nhất chẳng hạn?

Chi tiết:

Tôi có 100k biz ghi mỗi cái với mạng và kinh độ. Tôi thấy rằng MySQL thực sự hỗ trợ một kiểu dữ liệu gọi là điểm. Tôi có nên sử dụng nó thay thế?

MySQL có hỗ trợ hệ thống lưu trữ KDTree không http://en.wikipedia.org/wiki/File:KDTree-animation.gif

Có phải là tốt nhất để sử dụng kiểu dữ liệu điểm thay vì kiểu dữ liệu float thông thường để lưu trữ latitutude và kinh độ?

Cuối cùng, tôi muốn tìm những thứ như 100 nhà hàng đầu tiên gần điểm 105,6 nhất và cơ sở dữ liệu của tôi chứa rất nhiều điểm và điểm. Rõ ràng tính toán khoảng cách từng cái một cho mỗi bản ghi và cho mọi điểm sẽ là O (n) và do đó rất tệ.

Lưu ý rằng tôi biết về một giải pháp đơn giản hơn được mô tả trong Làm thế nào để Ứng dụng như Yelp Lấy thông tin khoảng cách từ cơ sở dữ liệu một cách hiệu quả và sẽ thực hiện chính tôi để bắt đầu. Đó là một câu trả lời tốt.

Tuy nhiên, tôi nghĩ rằng có một tiêu chí của câu trả lời cây trồng nên vượt trội hơn phải không? Trong thực tế, việc lưu trữ vị trí dựa trên vĩ độ và kinh độ và tìm kiếm những thứ gần nhất với nó là một vấn đề rất phổ biến, tôi hy vọng mysql có một mẫu thiết kế đặc biệt cho điều đó. Nó có cái đó không?

Tôi có thể tìm hiểu thêm về nó ở đâu? Cảm ơn.



Có vẻ như giải pháp ở đây dba.stackexchange.com/questions/4210/ đã là giải pháp tốt nhất. Ý tôi là có một thứ gọi là MYSQL không gian. Tuy nhiên, bạn không thể lấy ra những thứ như vị trí (khoảng cách (x) <20). Nó chưa được thực hiện.
dùng4951

Câu trả lời:


11

Theo như các mẫu thiết kế, câu hỏi của Yelp là những thứ khá chuẩn.

Đối với một câu trả lời phức tạp hơn, có lẽ bạn sẽ cần khoảng cách không gian địa lý. Đây là một powerpoint hấp dẫn về chủ đề đó (và đây cũng là phiên bản pdf của chủ đề đó). Tuy nhiên, toán học liên quan là khá xấu xí.

Từ slide của họ:

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

Có một câu trả lời dài hơn, sâu hơn về khoảng cách không gian địa lý trên Stack Overflow .

Nhưng bạn vẫn muốn giới hạn kết quả theo vĩ độ và kinh độ.

Cuối cùng, tôi sẽ tránh kiểu dữ liệu POINT và đi theo vĩ độ / kinh độ. Hiện tại không có cách nào để xác định khoảng cách giữa hai ĐIỂM, vì vậy bạn sẽ phải lưu trữ vĩ độ / kinh độ cho cách tính toán đó.

Một liên kết cuối cùng: bạn cũng có thể muốn kiểm tra luồng SO này liên quan đến việc tăng tốc các truy vấn bằng cách sử dụng các chỉ mục không gian.


[ERROR trong truy vấn 4] Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp đúng để sử dụng gần '- Dest.lon) * pi () / 180/2), 2))) như khoảng cách TỪ mạng_pose mệnh có d' ở dòng 2
Felipe

Xin chào, @dist là trên milles? cảm ơn
Jorge Olaf Erlandsen

1
@OlafErlandsen có trong dặm
Jan van der Vegt

4

Kiểu dữ liệu điểm là OK; bạn chỉ có thể gọi X (tọa độ) / Y (tọa độ) để nhận các giá trị Lat / Lon.

Ví dụ:

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 là lat và -122 là lon? Và 25 là mét hay km?
Felipe

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.