Masalahnya adalah cara Anda menyimpan data dalam database tidak cocok untuk jenis tugas yang Anda lakukan. Menggunakan Point
nilai dalam Geometry
titik data adalah cara untuk pergi. Sebenarnya mengkodekan sesuatu 4+ tahun yang lalu untuk tujuan ini, tetapi mengalami masalah dalam menemukannya. Tapi postingan ini tampaknya menutupinya dengan baik.
EDIT Oke, menemukan kode lama saya, tetapi mengacu pada data klien lama yang jelas tidak dapat saya bagikan. Tetapi kunci untuk mempercepat dengan koordinat dalam database menggunakan POINT
data disimpan dalam tabel database dengan tipe GEOMETRY
. Detail selengkapnya di sini
di situs resmi MySQL. Karena saya membutuhkan alasan untuk meninjau kembali jenis kode ini—dan konsepnya—untuk sementara, inilah skrip MySQL cepat yang saya buat untuk membuat tabel sampel dengan data sampel untuk menyampaikan konsep dasar. Setelah Anda memahami apa yang terjadi, itu akan membuka banyak opsi keren.
Juga ditemukan penjelasan hebat/sederhana ini konsep juga.
Dan menemukan penilaian data spasial hebat lainnya di MySQL 5.6. Banyak info bagus tentang indeks &kinerja. Khusus mengenai kinerja indeks spasial MySQL:
Dan di sisi lain itu:
Dan inilah skrip pengujian MySQL dasar saya untuk membantu mengilustrasikan konsep:
/* 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
;