Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Was ist der beste Ansatz, um alle Adressen zu finden, die sich in einer bestimmten Entfernung zum ausgewählten Punkt befinden?

Als ich dies in MySQL implementiert habe (zum Speichern von Orten auf einer abgeflachten Sphäre, was im Grunde das ist, was die Erde ist (ich nehme an, Sie sprechen von der Erde!)), habe ich so viele vorberechnete Informationen wie möglich in der Datenbank gespeichert. Also für eine Zeile, die latitude speichert und longitude , berechne ich auch zum Zeitpunkt des Einfügens die folgenden Felder:

  • radiansLongitude (Math.toRadians(longitude) )
  • sinRadiansLatitude (Math.sin(Math.toRadians(latitude) )
  • cosRadiansLatitude (Math.cos(Math.toRadians(latitude) )

Wenn ich dann nach den Orten suche, die innerhalb von X Einheiten des latitude liegen /longitude In Frage, meine vorbereitete Aussage ist wie folgt:

from Location l where
    acos(
        sin(:latitude) * sinRadiansLatitude + 
        cos(:latitude) * cosRadiansLatitude * 
        cos(radiansLongitude - :longitude) 
        ) * YYYY < :distance
    and l.latitude>:minimumSearchLatitude
    and l.latitude<:maximumSearchLatitude 
    and l.longitude>:minimumSearchLongitude 
    and l.longitude<:maximumSearchLongitude 
    order by acos(
                sin(:latitude) * sinRadiansLatitude + 
                cos(:latitude) * cosRadiansLatitude * 
                cos(radiansLongitude - :longitude)  
        ) * YYYY asc

Wobei YYYY =3965 gibt Ihnen Entfernungen in Meilen oder YYYY =6367 kann für Entfernungen in km verwendet werden.

Schließlich habe ich die maximumSearchLatitude verwendet / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude Parameter, um die Mehrheit der Punkte aus der Ergebnismenge auszuschließen, bevor die Datenbank irgendwelche Berechnungen durchführen muss. Sie können dies benötigen oder auch nicht. Wenn Sie dies verwenden, liegt es an Ihnen, welche Werte Sie für diese Parameter auswählen, da dies davon abhängt, wonach Sie suchen.

Offensichtlich sind vernünftige Anwendungen von Indizes in der Datenbank erforderlich.

Der Vorteil dieses Ansatzes besteht darin, dass die Informationen, die sich nie ändern, aber jedes Mal benötigt werden, nur einmal berechnet werden, während die Werte von radiansLongitude berechnet werden , sinRadiansLatitude , cosRadiansLatitude denn jede Zeile wird jedes Mal, wenn Sie eine Suche durchführen, sehr schnell sehr teuer.

Die andere Option ist die Verwendung eines Geodatenindex , was bedeutet, dass all dies von der Datenbank für Sie erledigt wird. Ich weiß allerdings nicht, wie gut sich Hibernate damit integrieren lässt.

Haftungsausschluss:Es ist lange her, dass ich mir das angesehen habe, und ich bin kein GIS-Experte!