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

Geolokační dotaz MySQL

Problém je v tom, že způsob, jakým ukládáte data do databáze, není vhodný pro typ úlohy, kterou provádíte. Pomocí Point hodnoty v Geometry datové body jsou správnou cestou. Ve skutečnosti jsem pro tento účel zakódoval něco před 4 a více lety, ale měl jsem problémy to najít. Ale tento příspěvek zdá se, že to dobře zakrývá.

UPRAVIT Dobře, našel jsem svůj starý kód, ale odkazuje na stará klientská data, která samozřejmě nemohu sdílet. Ale klíčem k rychlosti se souřadnicemi v databázích je použití POINT data uložená v databázové tabulce s typem GEOMETRY . Další podrobnosti zde na oficiálních stránkách MySQL. Protože jsem nějakou dobu potřeboval důvod k tomu, abych se znovu podíval na tento typ kódu – a koncepty –, zde je rychlý skript MySQL, který jsem vymrštil, abych vytvořil ukázkovou tabulku s ukázkovými daty pro vyjádření základních konceptů. Jakmile pochopíte, co se děje, otevře se vám spousta skvělých možností.

Také jsme našli toto skvělé/jednoduché vysvětlení konceptu také.

A našel jsem další skvělé hodnocení prostorových dat v MySQL 5.6. Spousta skvělých informací o indexech a výkonu. Konkrétně ohledně výkonu prostorového indexu MySQL:

A na druhé straně:

A zde jsou mé základní testovací skripty MySQL, které vám pomohou ilustrovat tento koncept:

/* Create the database `spatial_test` */
CREATE DATABASE `spatial_test` CHARACTER SET utf8 COLLATE utf8_general_ci;

/* Create the table `locations` in `spatial_test` */
CREATE TABLE `spatial_test`.`locations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `coordinates` point NOT NULL,
  UNIQUE KEY `id` (`id`),
  SPATIAL KEY `idx_coordinates` (`coordinates`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

/* Insert some test data into it. */
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(27.174961 78.041822)'));
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(27.985818 86.923596)'));
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(44.427963 -110.588455)'));
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(19.896766 -155.582782)'));
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(40.748328 -73.985560)'));
INSERT INTO `spatial_test`.`locations` (`id`, `coordinates`) VALUES (NULL, GeomFromText('POINT(40.782710 -73.965310)'));

/* A sample SELECT query that extracts the 'latitude' & 'longitude' */
SELECT x(`spatial_test`.`locations`.`coordinates`) AS latitude, y(`spatial_test`.`locations`.`coordinates`) AS longitude FROM `spatial_test`.`locations`;

/* Another sample SELECT query calculates distance of all items in database based on GLength using another set of coordinates. */
SELECT GLength(LineStringFromWKB(LineString(GeomFromText(astext(PointFromWKB(`spatial_test`.`locations`.`coordinates`))), GeomFromText(astext(PointFromWKB(POINT(40.782710,-73.965310))))))) AS distance
FROM `spatial_test`.`locations`
;

/* Yet another sample SELECT query that selects items by using the Earth’s radius. The 'HAVING distance < 100' equates to a distance of less than 100 miles or kilometers based on what you set the query for. */
/* Earth’s diameter in kilometers: 6371 */
/* Earth’s diameter in miles: 3959 */
SELECT id, (3959 * acos(cos(radians(40.782710)) * cos(radians(x(`spatial_test`.`locations`.`coordinates`))) * cos(radians(y(`spatial_test`.`locations`.`coordinates`)) - radians(-73.965310)) + sin(radians(40.782710)) * sin(radians(x(`spatial_test`.`locations`.`coordinates`))))) AS distance 
FROM `spatial_test`.`locations`
HAVING distance < 100
ORDER BY id
;



  1. FOR XML PATH(''):Escapování speciálních znaků

  2. seznam všech tabulek v databázi s MySQLi

  3. jak odstranit duplicitní hodnoty v tabulce mysql

  4. Jak získat seznam měsíců mezi 2 danými daty pomocí dotazu?