Mysql
 sql >> Database >  >> RDS >> Mysql

Qual è l'approccio migliore per trovare tutti gli indirizzi che si trovano a una distanza specifica dal punto selezionato

Quando l'ho implementato in MySQL (per memorizzare i luoghi su una sfera oblata, che è fondamentalmente ciò che è la terra (presumo che tu stia parlando della terra!)), ho memorizzato quante più informazioni precalcolate possibile nel database. Quindi, per una riga che memorizza latitude e longitude , calcolo al momento dell'inserimento anche i seguenti campi:

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

Quindi, quando cerco i luoghi che si trovano entro X unità di latitude /longitude in questione, la mia dichiarazione preparata è la seguente:

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

Dove YYYY =3965 ti dà le distanze in miglia o YYYY =6367 può essere utilizzato per le distanze in km.

Infine, ho utilizzato maximumSearchLatitude / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude parametri per escludere la maggior parte dei punti dal set di risultati prima che il database debba eseguire calcoli. Potresti aver bisogno o meno di questo. Se lo utilizzi, dipenderà da te quali valori scegliere per questi parametri, poiché dipenderà da ciò che stai cercando.

Ovviamente saranno necessarie oculate applicazioni degli indici nel database.

Il vantaggio di utilizzare questo approccio è che le informazioni che non cambiano mai ma sono necessarie ogni volta vengono calcolate solo una volta, mentre si calcolano i valori di radiansLongitude , sinRadiansLatitude , cosRadiansLatitude per ogni riga ogni volta che esegui una ricerca diventerà molto costosa molto velocemente.

L'altra opzione consiste nell'usare un indice geospaziale , il che significa che tutto questo viene gestito per te dal database. Tuttavia, non so quanto bene Hibernate si integri con quello.

Disclaimer:è passato molto tempo dall'ultima volta che ho guardato questo e non sono un esperto di GIS!