sql >> Database >  >> RDS >> Mysql

Geolocatie MySQL-query

Het probleem is dat de manier waarop u gegevens in de database opslaat, niet geschikt is voor het soort taak dat u uitvoert. Point gebruiken waarden in Geometry datapunten is de juiste keuze. Eigenlijk iets van 4+ jaar geleden voor dit doel gecodeerd, maar problemen om het te vinden. Maar dit bericht lijkt het goed te dekken.

BEWERKEN Oké, ik heb mijn oude code gevonden, maar die verwijst naar oude klantgegevens die ik natuurlijk niet kan delen. Maar de sleutel tot snelheid met coördinaten in databases is het gebruik van POINT gegevens opgeslagen in de databasetabel met het type GEOMETRY . Meer details hier op de officiële MySQL-site. Omdat ik een reden nodig had om dit type code - en de concepten - een tijdje opnieuw te bekijken, is hier een snel MySQL-script dat ik heb gemaakt om een ​​voorbeeldtabel te maken met voorbeeldgegevens om de basisconcepten over te brengen. Als je eenmaal begrijpt wat er aan de hand is, ontstaan ​​er veel coole opties.

Vond ook deze geweldige/eenvoudige uitleg ook van het concept.

En vond nog een geweldige beoordeling van ruimtelijke gegevens in MySQL 5.6. Veel geweldige informatie over indexen en prestaties. Specifiek met betrekking tot de prestaties van de ruimtelijke index van MySQL:

En aan de andere kant:

En hier zijn mijn basis MySQL-testscripts om het concept te illustreren:

/* 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. HAS_DBACCESS() – Ontdek of een gebruiker toegang heeft tot een database in SQL Server

  2. 5 manieren om de fout "Delen door nul" in SQL Server op te lossen (Msg 8134)

  3. Hoe een MySQL-databasegebruiker in cPanel te verwijderen

  4. Veranderingen in de Oracle-interface