2009-02-09 15 views
6

Tôi có một danh sách các bản ghi trong cơ sở dữ liệu của tôi và mỗi bản ghi được liên kết với một mã zip.cách tốt nhất để truy vấn cơ sở dữ liệu cho các hồ sơ trong vòng n dặm của một mã zip là gì?

các "thực hành tốt nhất" để truy vấn tất cả các bản ghi trong cơ sở dữ liệu của tôi để tìm tất cả các mục có trong n dặm của một mã zip là gì?

Mỗi mã zip có một lat/long liên kết với nó trong cơ sở dữ liệu vì vậy tôi biết tôi sẽ phải sử dụng nó. Tuy nhiên, tôi không thể tưởng tượng chạy bất kỳ loại công thức khoảng cách trên mỗi cặp mã zip, chuyển sang dặm và từ chối những người không nằm trong bán kính của tôi.

Điều đó có vẻ tốn kém về mặt tính toán đối với một truy vấn phổ biến như vậy.

Tôi cũng đã cân nhắc thực hiện tính toán trước tất cả các cặp nhưng có vẻ quá lớn để xem xét. Có khoảng ~ 40.000 mã zip ở Hoa Kỳ. Vì vậy, một cơ sở dữ liệu tất cả các cặp của mỗi mã zip sẽ là (40.000)^2, hoặc 1,6 tỷ mục.

Tôi biết đây là vấn đề phổ biến trên các trang web để hy vọng ai đó có thể chỉ cho tôi đúng hướng cho cách tốt nhất. Tôi đang sử dụng SQL Server 2008 và nếu có giải pháp được tạo trước đó thì tuyệt vời, bởi vì tôi thực sự không muốn phát minh lại bánh xe trong trường hợp này.


Câu hỏi liên quan: Getting all zip codes within radius (điều này không giúp tôi)
Ngoài ra, tôi biết về dự án SourceForge này nhưng nó là vô chủ và không còn sử dụng.

Trả lời

7

tôi sẽ chạy một truy vấn mà trả lại tất cả hồ sơ trong ngoặc vuông trong phong bì vuông encompasing vòng tròn tìm kiếm xuyên tâm (minlat < lat < maxlat và minlong < dài < maxlong), và sau đó sau quá trình này để trả lại chỉ điểm trong bán kính vòng tròn chính nó. (Đảm bảo rằng các trường vĩ độ và dài của bạn được lập chỉ mục).

Nếu bạn muốn trở nên lạ mắt, máy chủ SQL hỗ trợ spatial indexes.

+0

dang: đánh bại tôi vào nó! –

0

Đây là một vấn đề rất khó giải quyết. Tôi sẽ khuyên bạn nên làm một số gian lận bằng cách tạo trước một cơ sở dữ liệu. Tạo một mạng lưới của bất cứ loại gần gũi bạn cần phải tìm, ví dụ, lấy mỗi 10 dặm trong mỗi hướng, thêm một mục vào cơ sở dữ liệu cho mỗi zip cho điểm lưới và khoảng cách, và sau đó khi một truy vấn đến, bạn đầu tiên dịch điểm truy vấn đến một trong các điểm lưới của bạn. Bây giờ bạn có thể tra cứu khoảng cách khá dễ dàng.

Giải pháp này về cơ bản có nghĩa là không gian giao dịch trong thời gian, vì vậy bạn có thể nhanh chóng có được cơ sở dữ liệu khá lớn. Tin tốt là: nó là dữ liệu rất dễ dàng để lập chỉ mục.

+0

Tất cả các cặp tính toán trước sẽ là loại lớn. Aprox. 40.000 mã zip của chúng tôi, vì vậy (40.000)^2 cho mỗi phạm vi sẽ có rất nhiều mục nhập cơ sở dữ liệu. – mmcdole

+0

Đó sẽ là aprox ~ 1,6 tỷ mục cho mỗi phạm vi ... Tôi không biết nếu đó sẽ là một lựa chọn. – mmcdole

+0

thực tế những gì Ola Bini gợi ý là bạn có thể rút ngắn thời lượng mục rất nhiều nếu bạn có thể giới hạn khoảng cách tối đa giữa các mã zip (10 dặm trong ví dụ của mình) – tehvan

3

tôi chạy a site that needs to run this query about once per second per user, và đây là những gì tôi đã học được:

Trước hết, hãy chắc chắn bảng vị trí của bạn có chỉ số về Lạt và Lớn. Đó là sự khác biệt giữa thời gian phản hồi 20ms và 15 giây nếu bạn có hàng triệu bản ghi.

Bắt đầu với truy vấn hộp giới hạn để có được một tập hợp các vị trí hoạt động. Sau đó tính toán khoảng cách trên những người, sắp xếp, và nếu bạn đang cầu kỳ về độ chính xác, lọc một vài ra.

Thành thật mà nói, tôi sẽ không lo lắng về việc tính toán trước mọi thứ.Như tôi đã nói, tôi chạy loại truy vấn này đối với bảng vị trí với 6.000.000 mục nhập và nó thường trả về kết quả trong < 50ms. Tùy thuộc vào nhu cầu của bạn, điều đó thực sự nhanh chóng đủ nhanh.

Chúc may mắn!

+0

Cảm ơn thông tin cá nhân của bạn về vấn đề này. Tôi đánh giá cao nó. – mmcdole

0

Bạn nên xem GeoNames.org. Bạn có thể truy vấn webservice của họ cho những gì bạn đang tìm kiếm hoặc bạn có thể dl cơ sở dữ liệu của họ.

Các vấn đề liên quan