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

výpočty vzdálenosti v dotazech mysql

Možnost 1:Proveďte výpočet v databázi přepnutím na databázi, která podporuje GeoIP.

Možnost 2:Proveďte výpočet v databázi pomocí uložené procedury takto:

CREATE FUNCTION calcDistance (latA double, lonA double, latB double, LonB double)
    RETURNS double DETERMINISTIC
BEGIN
    SET @RlatA = radians(latA);
    SET @RlonA = radians(lonA);
    SET @RlatB = radians(latB);
    SET @RlonB = radians(LonB);
    SET @deltaLat = @RlatA - @RlatB;
    SET @deltaLon = @RlonA - @RlonB;
    SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
    COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
    RETURN 2 * ASIN(SQRT(@d)) * 6371.01;
END//

Pokud máte v databázi index zeměpisné šířky a délky, můžete snížit počet výpočtů, které je třeba vypočítat, vytvořením počátečního ohraničujícího rámečku v PHP ($minLat, $maxLat, $minLong a $maxLong) a omezením řádky do podmnožiny vašich záznamů na základě toho (WHERE latitude BETWEEN $minLat AND $maxLat AND longitude BETWEEN $minLong AND $maxLong). Potom MySQL potřebuje pouze provést výpočet vzdálenosti pro tuto podmnožinu řádků.

Pokud k výpočtu vzdálenosti jednoduše používáte uloženou proceduru), pak SQL stále musí projít každý záznam ve vaší databázi a vypočítat vzdálenost pro každý záznam ve vaší databázi, než se může rozhodnout, zda daný řádek vrátit nebo jej zahodit. .

Vzhledem k tomu, že výpočet je relativně pomalý, bylo by lepší, kdybyste mohli zmenšit sadu řádků, které je třeba vypočítat, a eliminovat řádky, které jasně přesahují požadovanou vzdálenost, takže provádíme pouze nákladný výpočet pro menší počet řádků.

Pokud uvážíte, že to, co děláte, je v podstatě kreslení kruhu na mapě se středem na váš počáteční bod as poloměrem vzdálenosti; pak vzorec jednoduše identifikuje, které řádky spadají do tohoto kruhu... ale stále musí kontrolovat každý jednotlivý řádek.

Použití ohraničovacího rámečku je jako nakreslení čtverce na mapu nejprve s levým, pravým, horním a spodním okrajem v příslušné vzdálenosti od našeho středu. Náš kruh se pak nakreslí do tohoto rámečku, přičemž nejsevernější, nejvýchodnější, nejjižnější a nejzápadnější body na kruhu se dotýkají okrajů rámečku. Některé řádky vypadnou mimo toto pole, takže SQL se ani neobtěžuje zkoušet vypočítat vzdálenost pro tyto řádky. Počítá pouze vzdálenost pro ty řádky, které spadají do ohraničovacího rámečku, aby zjistil, zda spadají také do kruhu.

V rámci vašeho PHP (předpokládáme, že používáte PHP z názvu proměnné $), můžeme použít velmi jednoduchý výpočet, který určí minimální a maximální zeměpisnou šířku a délku na základě naší vzdálenosti, a poté tyto hodnoty nastavit v klauzuli WHERE vašeho SQL. prohlášení. Toto je fakticky naše krabice a vše, co spadne mimo ni, je automaticky vyřazeno, aniž by bylo nutné skutečně počítat její vzdálenost.

Toto je dobré vysvětlení (s kódem PHP) na movable Type webové stránky to by mělo být základní čtení pro každého, kdo plánuje provádět jakoukoli práci GeoPositioning v PHP.

UPRAVIT Hodnota 6371,01 v uložené proceduře calcDistance je násobitel, který vám poskytne vrácený výsledek v kilometrech. Pokud chcete získat míle, námořní míle, metry, cokoliv

, použijte vhodné alternativní násobiče

  1. Získejte polygonové body mysql

  2. Chyba MySQL:Máte chybu v syntaxi SQL; podívejte se do manuálu, který odpovídá verzi vašeho serveru MySQL, kde najdete správnou syntaxi

  3. Jaký je nejlepší datový typ pro ukládání URL v databázi MySQL?

  4. Jak rozdělit řetězec názvu v mysql?