文章目录
-
- 案例
-
- 建表
- 插入数据
- 查询
-
- 基础查询:查看刚才插入的数据
- 范围查询:找出某个矩形区域内的店铺
- [进阶查询:查找离我最近的店铺(KNN 最近邻搜索)](#进阶查询:查找离我最近的店铺(KNN 最近邻搜索))
- 常用空间类型
mysql本身并不支持r树索引,但是支持空间索引,底层就是r树。
注意经纬度的顺序,维度在前,经度在后,当然也可以指定。
案例
建表
sql
CREATE TABLE shops (
id INT PRIMARY KEY,
name VARCHAR(100),
-- 使用 POINT 空间类型存储经纬度,并指定 SRID 4326(WGS84标准坐标系)
location POINT NOT NULL,
-- 创建空间索引(底层就是 R树索引)
SPATIAL INDEX(location)
) ENGINE=InnoDB;
注:point类型从dbeaver界面新增是找不到的,就用sql新增吧。
插入数据
sql
INSERT INTO shops (id, name, location) VALUES
(1, '天安门纪念品店', ST_GeomFromText('POINT(39.909 116.397)', 4326)),
(2, '故宫咖啡厅', ST_GeomFromText('POINT(39.915 116.390)', 4326)),
(3, '王府井百货', ST_GeomFromText('POINT(39.911 116.410)', 4326)),
(4, '西单大悦城', ST_GeomFromText('POINT(39.910 116.373)', 4326));
查询
基础查询:查看刚才插入的数据
因为空间数据在 MySQL 内部是二进制存储的,直接 SELECT 会看不懂,所以需要用 ST_AsText 函数把它转回我们能看懂的文本格式。
sql
SELECT
id,
name,
ST_AsText(location) AS location_text
FROM shops;
范围查询:找出某个矩形区域内的店铺
假设我们要框选北京二环内的一小块区域,看看这里面有哪些店。我们可以用 MBRContains 函数,它会利用 R树索引,快速找出落在指定"最小包围矩形(MBR)"内的点:
sql
SELECT
name,
ST_AsText(location)
FROM shops
WHERE MBRContains(
-- 坐标顺序改为:纬度在前,经度在后 (左下 -> 右下 -> 右上 -> 左上 -> 回到左下)
ST_GeomFromText('POLYGON((39.90 116.38, 39.90 116.40, 39.92 116.40, 39.92 116.38, 39.90 116.38))', 4326),
location
);
进阶查询:查找离我最近的店铺(KNN 最近邻搜索)
sql
SELECT
name,
-- 计算球面距离,结果单位是米
ST_Distance_Sphere(location, ST_GeomFromText('POINT(39.903 116.428)', 4326)) AS distance_in_meters
FROM shops
ORDER BY location <=> ST_GeomFromText('POINT(39.903 116.428)', 4326)
LIMIT 2;
常用空间类型
上述案例用的point,但是point并不是唯一的空间索引,常见的如下:
| 类型 | 含义 | 典型应用场景 |
|---|---|---|
| POINT | 单个坐标点 | 门店位置、打车起点/终点 |
| LINESTRING | 连续的线段 | 道路、河流、运动轨迹 |
| POLYGON | 封闭的多边形区域 | 行政区划、商圈、园区范围 |
| MULTI*** | 多个同类型对象的集合 | 群岛(多面)、公交站点群(多点) |