sql >> Database >  >> RDS >> Mysql

Wat is de beste aanpak om alle adressen te vinden die zich op een bepaalde afstand tot het geselecteerde punt bevinden?

Toen ik dit heb geïmplementeerd in MySQL (voor het opslaan van plaatsen op een afgeplatte bol, wat in feite is wat aarde is (ik neem aan dat je het over aarde hebt!)), heb ik zoveel mogelijk vooraf berekende informatie opgeslagen in de database. Dus voor een rij die latitude . opslaat en longitude , bereken ik op het moment van invoegen ook de volgende velden:

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

Als ik vervolgens zoek naar de plaatsen die binnen X-eenheden van de latitude liggen, /longitude in kwestie is mijn voorbereide verklaring als volgt:

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

Waar YYYY =3965 geeft u afstanden in mijlen of YYYY =6367 kan worden gebruikt voor afstanden in km.

Ten slotte heb ik de maximumSearchLatitude . gebruikt / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude parameters om de meeste punten uit de resultatenset uit te sluiten voordat de database berekeningen moet uitvoeren. Misschien heb je dit wel of niet nodig. Als u dit wel gebruikt, is het aan u welke waarden u kiest voor deze parameters, aangezien dit afhankelijk is van wat u zoekt.

Uiteraard zullen oordeelkundige toepassingen van indexen in de database noodzakelijk zijn.

Het voordeel van deze benadering is dat de informatie die nooit verandert maar elke keer nodig is, slechts één keer wordt berekend, terwijl de waarden van radiansLongitude worden berekend. , sinRadiansLatitude , cosRadiansLatitude voor elke rij elke keer dat u een zoekopdracht uitvoert, wordt het erg snel erg duur.

De andere optie is om een ​​geospatiale index te gebruiken , wat betekent dat dit allemaal voor u wordt afgehandeld door de database. Ik weet echter niet hoe goed Hibernate daarmee integreert.

Disclaimer:het is lang geleden dat ik hier naar heb gekeken, en ik ben geen GIS-expert!



  1. Unieke beperking die twee kolommen in MySQL controleert

  2. Voorwaardelijke WHERE-clausule in SQL Server

  3. Verbinding maken met de PostgreSQL-database via SSH-tunneling in Python

  4. Inleiding tot Storage Spaces Direct voor SQL Server