sql >> Databáze >  >> RDS >> Mysql

Jaký je nejlepší přístup k nalezení všech adres, které jsou v určité vzdálenosti od vybraného bodu

Když jsem to implementoval v MySQL (pro ukládání míst na zploštělé kouli, což je v podstatě země (předpokládám, že mluvíte o zemi!)), uložil jsem do databáze co nejvíce předem vypočítaných informací. Tedy pro řádek, který ukládá latitude a longitude , při vkládání také vypočítám následující pole:

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

Když pak hledám místa, která jsou v rámci X jednotek latitude /longitude v otázce, moje připravené prohlášení je následující:

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

Kde YYYY =3965 vám udává vzdálenosti v mílích nebo YYYY =6367 lze použít pro vzdálenosti v km.

Nakonec jsem použil maximumSearchLatitude / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude parametry k vyloučení většiny bodů z výsledkové sady předtím, než databáze musí provést jakékoli výpočty. Můžete a nemusíte to potřebovat. Pokud toto použijete, bude na vás, jaké hodnoty pro tyto parametry zvolíte, protože to bude záviset na tom, co hledáte.

Je zřejmé, že uvážlivé aplikace indexů v databázi budou nezbytné.

Výhoda použití tohoto přístupu spočívá v tom, že informace, které se nikdy nemění, ale jsou potřebné pokaždé, se vypočítávají pouze jednou, zatímco při výpočtu hodnot radiansLongitude , sinRadiansLatitude , cosRadiansLatitude protože každý řádek pokaždé, když provedete vyhledávání, bude velmi rychle velmi drahý.

Druhou možností je použít geoprostorový index , což znamená, že toto vše za vás vyřídí databáze. Nevím, jak dobře se s tím Hibernate integruje.

Zřeknutí se odpovědnosti:Už je to dlouho, co jsem se na to díval, a nejsem odborník na GIS!



  1. Jak resetovat kořenové heslo MySQL

  2. Jak přečtu tento textový soubor a vložím jej do MySQL?

  3. SQL Server a zranitelnosti Spectre/Meltdown

  4. Nepodařilo se připojit k mysql na 127.0.0.1:3306 s uživatelem root přístup odepřen pro uživatele 'root'@'localhost' (pomocí hesla:YES)