MySQL Geography Point插入及范围查询求助(phpMyAdmin环境)
嘿,我来帮你搞定MySQL坐标插入和距离查询的问题!之前用phpMyAdmin折腾地理数据的时候踩过不少坑,给你分享些亲测可行的步骤和示例:
第一步:先创建合适的表结构
MySQL支持两种存储地理坐标的方式,我都给你列出来,选适合你的就行:
方式1:单独的经纬度字段(简单直观,适合新手)
这种方式不用搞复杂的空间类型,直接用小数字段存纬度和经度:
- 在phpMyAdmin里新建表,比如叫
locations,字段设置如下:id:INT,自增,设为主键name:VARCHAR(100),用来存地点名称latitude:DECIMAL(10,8),纬度范围是-90到90,保留8位小数足够精确longitude:DECIMAL(11,8),经度范围是-180到180
- 插入数据的SQL示例(在phpMyAdmin的「SQL」标签里执行):
INSERT INTO locations (name, latitude, longitude) VALUES ('北京天安门', 39.90420000, 116.40740000), ('上海东方明珠', 31.23040000, 121.47370000), ('广州塔', 23.10670000, 113.32450000);
方式2:MySQL空间类型POINT(专业级,适合复杂地理操作)
如果以后要做更多地理相关的查询(比如范围、交集),推荐用空间类型,记得建空间索引提升性能:
- 创建表的SQL:
CREATE TABLE locations_spatial ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), coords POINT NOT NULL, SPATIAL INDEX(coords) -- 空间索引,加速地理查询 );
- 插入数据的注意点:敲黑板!POINT类型的顺序是「经度在前,纬度在后」,别搞反了!两种插入写法都可以:
-- 写法1:用ST_GeomFromText函数兼容旧版本MySQL INSERT INTO locations_spatial (name, coords) VALUES ('北京天安门', ST_GeomFromText('POINT(116.4074 39.9042)')), ('上海东方明珠', ST_GeomFromText('POINT(121.4737 31.2304)')); -- 写法2:用POINT()函数(MySQL 5.6+支持,更简洁) INSERT INTO locations_spatial (name, coords) VALUES ('广州塔', POINT(113.3245, 23.1067));
第二步:查询指定距离范围内的坐标点
同样分两种方式对应上面的表结构:
针对单独经纬度字段:用Haversine公式计算球面距离
这个公式是计算地球表面两点距离的经典方法,适合用DECIMAL字段的场景。比如查询距离北京天安门(39.9042, 116.4074)100公里以内的地点:
SELECT name, latitude, longitude, -- 计算距离(单位:公里,6371是地球平均半径) 6371 * ACOS( COS(RADIANS(39.9042)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(116.4074)) + SIN(RADIANS(39.9042)) * SIN(RADIANS(latitude)) ) AS distance_km FROM locations HAVING distance_km <= 100 -- 过滤100公里以内的点 ORDER BY distance_km ASC; -- 按距离从近到远排序
小贴士:如果要算英里,把6371换成3956就行;
HAVING不能换成WHERE,因为distance_km是计算出来的字段。
针对空间类型POINT:用ST_Distance_Sphere函数(高效)
MySQL 5.7+内置了这个函数,直接计算球面距离,而且有空间索引的话速度会快很多。比如同样查询距离北京天安门100公里以内的点:
SELECT name, ST_AsText(coords) AS coordinates, -- 把POINT转成文本方便查看 ST_Distance_Sphere(coords, POINT(116.4074, 39.9042)) / 1000 AS distance_km -- 转成公里 FROM locations_spatial WHERE ST_Distance_Sphere(coords, POINT(116.4074, 39.9042)) <= 100000 -- 100公里=100000米 ORDER BY distance_km ASC;
额外的phpMyAdmin操作小技巧
- 手动插入POINT类型数据时,在phpMyAdmin的「插入」标签里,直接在
coords字段输入POINT(经度 纬度)就行,比如POINT(116.4074 39.9042)。 - 要查看POINT字段的内容,在查询时加上
ST_AsText(coords),就能看到可读的坐标文本。
内容的提问来源于stack exchange,提问作者Jack Wells
相关产品推荐
相关产品推荐

