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

Hvad er den bedste tilgang til at finde alle adresser, der er i en bestemt afstand til det valgte punkt

Når jeg har implementeret dette i MySQL (til lagring af steder på en oblate kugle, som i bund og grund er, hvad jorden er (jeg går ud fra, du taler om jorden!)), har jeg gemt så meget forudberegnet information som muligt i databasen. Altså for en række, der gemmer latitude og longitude , jeg beregner også ved indsættelsestidspunktet følgende felter:

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

Så når jeg søger efter de steder, der er inden for X enheder af latitude /longitude i spørgsmålet, er min udarbejdede erklæring som følger:

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

Hvor YYYY =3965 giver dig afstande i miles eller YYYY =6367 kan bruges til afstande i km.

Endelig har jeg brugt maximumSearchLatitude / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude parametre for at udelukke størstedelen af ​​punkter fra resultatsættet, før databasen skal udføre nogen beregninger. Du har muligvis brug for dette. Hvis du bruger dette, er det op til dig, hvilke værdier du vælger for disse parametre, da det vil afhænge af, hvad du søger.

Naturligvis vil velovervejede anvendelser af indekser i databasen være nødvendige.

Fordelen ved at bruge denne tilgang er, at den information, der aldrig ændrer sig, men som er nødvendig hver gang, kun beregnes én gang, mens beregning af værdierne af radiansLongitude , sinRadiansLatitude , cosRadiansLatitude for hver række, hver gang du udfører en søgning vil blive meget dyrt meget hurtigt.

Den anden mulighed er at bruge et geospatialt indeks , hvilket betyder, at alt dette håndteres for dig af databasen. Jeg ved dog ikke, hvor godt Hibernate integrerer med det.

Ansvarsfraskrivelse:det er længe siden, jeg har set på dette, og jeg er ikke en GIS-ekspert!



  1. Sequelize bulkCreate() returnerer NULL-værdi for primærnøgle

  2. Hvordan kan jeg kombinere flere rækker til en kommasepareret liste i SQL Server 2005?

  3. Undtagelse ORA-08103:objekt eksisterer ikke længere ved brug af setfetchsize af Hibernate

  4. Vælg første række af hver gruppe i sql