sql >> Databasteknik >  >> RDS >> Mysql

Geolokalisering MySQL-fråga

Problemet är att sättet du lagrar data i databasen inte lämpar sig för den typ av uppgift du utför. Använder Point värden i Geometry datapunkter är vägen att gå. Kodade faktiskt något för 4+ år sedan för detta ändamål, men har problem med att hitta det. Men det här inlägget verkar täcka det bra.

REDIGERA Okej, hittade min gamla kod, men den syftar på gamla klientdata som jag uppenbarligen inte kan dela. Men nyckeln till snabbare koordinater i databaser är att använda POINT data lagrade i databastabellen med typen GEOMETRY . Mer information här på den officiella MySQL-webbplatsen. Eftersom jag har behövt en anledning att återvända till den här typen av kod – och koncepten – ett tag är här ett snabbt MySQL-skript som jag skapade för att skapa en exempeltabell med exempeldata för att förmedla de grundläggande koncepten. När du väl förstår vad som händer öppnar det upp för många coola alternativ.

Hittade även denna bra/enkla förklaring av konceptet också.

Och hittade en annan bra bedömning av rumslig data i MySQL 5.6. Massor av bra information om index och prestanda. Specifikt angående MySQL rumsliga indexprestanda:

Och på andra sidan av det:

Och här är mina grundläggande MySQL-testskript för att illustrera konceptet:

/* 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. Hash vad? Förstå Hash Index

  2. Okänt kolumnfel i denna COUNT MySQL-sats?

  3. Något liknande Hibernate i PHP?

  4. Hur man återställer MySQL eller MariaDB Root Password i Linux