在日常开发中很经常需要处理地理位置信息,比如计算两个地点之间的距离、距离排序等。MySQL 提供了多种数据类型来存储地理位置信息,比如 POINTGeometry。本文主要介绍如何使用 POINT 类型。POINTGeometry 类型的一个子类,用于表示坐标空间中的单一位置。

先来看使用 POINT 类型常用的建表语句:

1
2
3
4
5
6
7
CREATE TABLE `locations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`address` varchar(255) NOT NULL,
`location` point NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表中的 location 字段用于存储地理位置信息,为了提升查询效率一般会在该字段上创建空间索引 (SPATIAL KEY),下面我们来插入一行记录:

1
INSERT INTO `locations` (`address`, `location`) VALUES ('广州市海珠区', POINT(113.33902824928715, 23.104983516845195));

POINT 类型字段值需要使用 POINT 函数来构造,参数 X 表示经度,Y 表示纬度。下面我们来查询写入的记录:

1
SELECT * FROM `locations`;

查询结果如下:

idaddresslocation
1广州市海珠区0x0000000001010000000000000000E03F0000000000000040

POINT 类型字段值是以二进制形式存储的,因此无法直接从 location 字段中获取到经纬度信息,需要借助 ST_XST_Y 函数从中提取经纬度信息:

1
2
3
4
SELECT ST_X(`location`) AS `longitude`,
ST_Y(`location`) AS `latitude`,
address
FROM locations

查询结果如下:

longitudelatitudeaddress
113.3390282492871523.104983516845195广州市海珠区

别名函数 XY 等效与 ST_XST_Y 函数:

1
2
3
4
SELECT X(`location`) AS `longitude`,
Y(`location`) AS `latitude`,
address
FROM locations

计算两点距离也是常见需求,例如获取距离用于最近的门店列表,可以使用 ST_Distance_Sphere 函数来完成:

1
2
3
SELECT ST_Distance_Sphere(POINT(113.45793492676519, 23.166846183324765), location) AS distance, address
FROM locations
ORDER BY distance;

执行结果如下:

distanceaddress
13969.443169469429广州市海珠区

ST_Distance_Sphere 函数返回的是两点之间的球面距离,单位是米。如果需要计算平面距离,可以使用 ST_Distance 函数。