sql >> Base de Datos >  >> RDS >> Mysql

¿Cuál es el mejor enfoque para encontrar todas las direcciones que están a una distancia específica del punto seleccionado?

Cuando implementé esto en MySQL (para almacenar lugares en una esfera achatada, que es básicamente lo que es la tierra (¡supongo que estás hablando de la tierra!)), almacené la mayor cantidad de información precalculada posible en la base de datos. Entonces, para una fila que almacena latitude y longitude , también calculo en el momento de la inserción los siguientes campos:

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

Luego, cuando busco los lugares que están dentro de X unidades de la latitude /longitude en cuestión, mi declaración preparada es la siguiente:

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

Donde YYYY =3965 te da las distancias en millas o YYYY =6367 se puede utilizar para distancias en km.

Finalmente, he usado maximumSearchLatitude / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude parámetros para excluir la mayoría de los puntos del conjunto de resultados antes de que la base de datos tenga que realizar cualquier cálculo. Puede o no necesitar esto. Si usa esto, dependerá de usted qué valores elija para estos parámetros, ya que dependerá de lo que esté buscando.

Obviamente, serán necesarias aplicaciones juiciosas de índices en la base de datos.

El beneficio de usar este enfoque es que la información que nunca cambia pero que se necesita cada vez solo se calcula una vez, mientras que el cálculo de los valores de radiansLongitude , sinRadiansLatitude , cosRadiansLatitude porque cada fila cada vez que realice una búsqueda se volverá muy costosa muy rápido.

La otra opción es usar un índice geoespacial , lo que significa que la base de datos se encarga de todo esto. Sin embargo, no sé qué tan bien se integra Hibernate con eso.

Descargo de responsabilidad:hace mucho tiempo que no miré esto, ¡y no soy un experto en GIS!