MySQL

创建日期:2024-06-21
更新日期:2025-01-20

版本:8.0.25(推荐版本:≥8.24)

MySQL空间扩展支持产生、存储和分析地理元素。

  1. 数据类型用于表示空间值。
  2. 函数用于操作空间值。
  3. 空间索引用于提高空间列的访问速度。

MySQL数据类型和函数支持MyISAM、InnoDB、NDB和Archive表。MyISAM和InnoDB支持SPATIAL和no-SPATIAL索引。其他引擎只支持no-SPATIAL索引。由于InnoDB是默认存储引擎,应采用InnoDB存储空间数据。

空间数据类型

//参考:《refman-8.0-en.pdf》11.4空间数据类型。//

几何类型

类型名称备注
geometry几何储存点、线、面、多点、多线、多面
geometrycollection几何集合支持储存任意几何的集合
point
linestring线
polygon
multipoint多点
multilinestring多线
multipolygon多面

示例:

create table geom (g geometry);

create table geom (

p point srid 0,

g geometry not null srid 4326

);

SRID表示空间参考系(SRS):例如:4326、3857

创建空间索引要求列:NOT NULL,并且有一个SRID。例如:

create table geom (g geometry not null srid 4326);

InnoDB表支持SRID值为笛卡尔和地理坐标系,MyISAM表限制SRID值为笛卡尔坐标系。

SRID属性对列的限制:

  1. 仅支持存储指定的SRID数据。
  2. 优化器可以在列上使用空间索引。

对于不加SRID属性的列:

  1. 没有SRID限制。
  2. 优化器不能创建空间索引。

层级结构

Geometry(不能实例化)

Point(可以实例化)

Curve(不能实例化)

LineString(可以实例化)

Line

LinearRing

Surface(不能实例化)

Polygon(可以实例化)

GeometryCollection(可以实例化)

MultiPoint(可以实例化)

MultiCurve(不能实例化)

MultiLinearString(可以实例化)

MultiSurface(不能实例化)

MultiPolygon(可以实例化)

Geometry类

Geometry属性:type, SRID, coordinates, interior, boundary, exterior, MBR(最小包围盒)或envelope。

SRID默认值为0,表示一个无限平坦的笛卡尔平面,坐标轴没有单位。计算时必须采用相同的SRID。

MBR格式:((minx miny, maxx miny, maxx maxy, minx maxy, minx miny))

分类:

  1. 简单或非简单:线、多点、多线。
  2. 闭合或非闭合:线、多线。
  3. 空或非空:

维度:-1表示空几何,0表示几何没有长度和面积,1表示有长度没面积,2表示有长度有面积。

Point类

Point属性:X、Y。

一个点是一个零维几何,范围是空集。

Curve类

曲线属性:一些点的坐标。

曲线是一维几何。

简单曲线:简单曲线不能通过一个点两次;但是开始点和结束点可以相同。

闭合曲线:曲线开始点和结束点相同。

闭合曲线的范围是空的。

非闭合曲线范围是两个端点。

一条曲线如果它既是简单的又是闭合的,那么它是一个LinearRing。

LineString类

LineString是一个曲线,它在点之间是线性插值的。

LineString属性:点的坐标。

LineString变成Line,如果它只有两个点。

LineString变成LineRing,如果它既闭合又简单。

Surface类

Surface是二维几何,不可实例化。

Surface属性:OpenGIS规范定义Surface是包含一个patch的几何,它关联了一个闭合区域和0个或多个内部边界。

一个简单Surface的范围是闭合曲线的外部或内部边界。

Polygon类

一个Polygon是一个平面,它有一个外部边界和0个或多个内部边界,内部边界表示面上的孔。

简单Polygon:

  1. Polygon边界包括一些线圈,这些线圈组成了它的外部和内部边界。
  2. Polygon不能包含相交的圈。Polygon边界上的圈可以相交于一点,但是只能作为切线。
  3. Polygon不能有线、尖刺或小孔。
  4. Polygon可以有一些点组成的内部。
  5. Polygon可以有空。一个有孔的外部边界不是连接的。

GeometryCollection类

MultiPoint类

MultiCurve类

MultiLineString类

MultiSurface类

MultiPolygon类

支持的空间数据类型

WKT格式

WKB格式

MySQL存储几何类似WKB,但是起始4个字节表示SRID。

SKT格式

一个点:POINT(15 20)

一条线:LINESTRING(0 0, 10 10, 20 25, 50 60)

一个面包括一个空:POLYGON((0 0, 10 0, 10 10, 10 0, 0 0), (5 5, 7 5, 7 7, 5 7, 5 5))

一个多点:MULTIPOINT(0 0, 20 20, 60 60)

一个多线:MULTILINESTRING((10 10, 20 20), (15 15, 30 15))

一个多面:MULTIPOLYGON~(~(~(0 0, 10 0, 10 10, 0 10, 0 0)), ((5 5, 7 5, 7 7, 5 7, 5 5~)~)~)

一个几何集合:GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))

示例1:SELECT ST_X(POINT(15, 20));;

示例2:SELECT ST_X(ST_GeomFromText(‘POINT(15, 20)’));

示例3:ST_MPointFromText(‘MULTIPOINT(1 1, 2 2, 3 3)’);

示例4:ST_MPointFromText(MULTIPOINT( (1 1), (2 2), ( 3 3 ) ));

WKB格式

组成:字节序(1比特)、WKB类型(4比特)、x坐标(8比特)、Y坐标(8比特)

内部储存类型

4比特SRID+WKB格式。

  1. 字节序是1,因为MySQL储存几何是小端字节序。
  2. 支持几何类型:Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection。
  3. 只有GeometryCollection允许为空。
  4. 面中的空支持顺时针和逆时针,读取数据时MySQL会自动翻转。

  1. 笛卡尔坐标:长度单位保存在空间参考系,X值保存在X,Y值保存在Y,坐标轴方向保存在空间参考系。
  2. 地理坐标:角度单位保存在空间坐标系,经度保存在X,纬度保存在Y,坐标轴方向保存在空间参考系。

LENGTH返回保存所需比特数。

示例:

SET @g = ST_GeomFromText(‘POINT(1 -1)’);

SELECT LENGTH(@g);

SELECT HEX(@g);

几何结构良好性和有效性

结构良好的:

  1. 线至少2个点。
  2. 面至少1个圈。
  3. 面圈是闭合的。
  4. 面圈至少4个点,第一个点和第四个点是相同的。
  5. 几何非空。(除了GeometryCollection)

有效的:

  1. 面不能跟自己相交。
  2. 面内部的圈在外部圈的内部。
  3. 多面不能有重叠的面。

判断几何是否有效:ST_IsValid函数

空间参考系支持

投影坐标系:

地理坐标系:

坐标系表在数据字典:mysql.st_spatial_reference_systems表,它是不可见的,可以通过INFORMATION_SCHEMA ST_SPATIAL_REFERENCE_SYSTEMS视图查询。

示例:SELECT * FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS WHERE SRS_ID=4326;

创建空间列

示例1:CREATE TABLE geom (g GEOMETRY);

示例2:ALTER TABLE geom ADD pt POINT;

示例3:ALTER TABLE geom DROP pt;

填充空间列

示例1:

INSERT INTO geom VALUES (ST_GeomFromText(‘POINT(1 1)’));

SET @g = ‘POINT(1 1)’;

INSERT INTO geom VALUES (ST_GeomFromText(@g));

示例2:

SET @g = ST_GeomFromText(‘POINT(1 1)’);

INSERT INTO geom VALUES (@g);

示例3:

SET @g = ‘LINESTRING(0 0, 1 1, 2 2)’;

INSERT INTO geom VALUES (ST_GeomFromText(@g));

SET @g = ‘POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7, 5 7, 5 5))’;

INSERT INTO geom VALUES (ST_GeomFromText(@g));

SET @g=’GEOMETRYCOLLECTION(POINT(1 1), LINESTRING(0 0, 1 1, 2 2, 3 3, 4 4))’;

INSERT INTO geom VALUES (ST_GeomFromText(@g));

示例4:

SET @g = ‘POINT(1 1)’;

INSERT INTO geom VALUES (ST_PointFromText(@g));

SET @g = ‘LINESTRING(0 0, 1 1, 2 2)’;

INSERT INTO geom VALUES (ST_LineStringFROMText(@g));

SET @g = ‘POLYGON((0,0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7, 5 7, 5 5))’;

INSERT INTO geom VALUES (ST_PolygonFromText(@g));

SET @g = ‘GEOMETRYCOLLECTION(POINT(1 1), LINESTRING(0 0, 1 1, 2 2, 3 3, 4 4))’;

INSERT INTO geom VALUES (ST_GeomCollFromText(@g));

获取空间数据

示例1:

CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;

示例2:

SELECT ST_AsText(g) FROM geom;

SELECT ST_AsBinary(g) FROM geom;

优化空间分析

MySQL使用二次方分裂R树来为空间列创建空间索引。

创建空间索引

示例1:

CREATE TABLE geom (g GEOMETRY NOT NULL SRID 4326, SPATIAL INDEX(g));

示例2:

CREATE TABLE geom (g GEOMETRY NOT NULL SRID 4326);

ALTER TABLE geom ADD SPATIAL INDEX(g);

示例3:

CREATE TABLE geom (g GEOMETRY NOT NULL SRID 4326);

CREATE SPATIAL INDEX g ON geom (g);

示例4:

ALTER TABLE geom DROP INDEX g;

示例5:

DROP INDEX g ON geom;

空间索引:R树,非空间索引:B树。

示例6:

DESCRIBE geom;

使用空间索引

示例1(查询多边形内元素):

SET @poly = ‘Polygon((30000 15000, 31000 15000, 31000 16000, 30000 16000, 30000 15000))’;

SELECT fid,ST_AsText(g) FROM geom WHERE MBRContains(ST_GeomFromText(@poly), g);

示例2(解析查询执行):

SET @poly = ‘Polygon((30000 15000, 31000 15000, 31000 16000, 30000 16000, 30000 15000))’;

EXPLAIN SELECT fid,ST_AsText(g) FROM geom WHERE MBRContains(ST_GeomFromText(@poly), g);

空间分析函数

//参考:《refman-8.0-en.pdf》12.17空间分析函数。//

名称简介
GeomCollection()通过几何构建几何集合
GeometryCollection()通过几何构建几何集合
LineString()通过点值创建LineString
MBRContains()一个几何包围盒是否包含另一个
MBRCoveredBy()一个几何包围盒是否被另一个包含
MBRCovers()一个几何包围盒是否包含另一个
MBRDisjoint()两个几何包围盒是否不相交
MBREquals()两个几何包围盒是否相等
MBRIntersects()两个几何包围盒是否相交
MBROverlaps()两个几何包围盒是否重叠
MBRTouches()两个几何包围盒是否接触
MBRWithin()一个几何包围盒是否在另一个中间
MultiLineString()使用LineString构建一个MultiLineString
MultiPoint()通过Point创建MultiPoint
MultiPolygon()通过Polygon创建MultiPolygon
Point()通过坐标创建一个点
Polygon()通过LineString创建一个Polygon
ST_Area()返回Polygon或MultiPolygon的面积
ST_AsBinary(),ST_AsWKB()将内部类型转为WKB
ST_AsGeoJSON()通过几何产生GeoJSON对象
ST_AsText(),ST_AsWKT()将内部几何转换为WKT
ST_Buffer()返回离几何一定距离的一些点
ST_Buffer_Strategy()为ST_Buffer()创建策略。
ST_Centroid()返回几何中心
ST_Collect()聚合空间值为几何(8.0.24后支持)
ST_Contains()一个几何是否包含另一个
ST_ConvexHull()返回几何凸包
ST_Crosses()一个几何是否穿过另一个
ST_Difference()返回两个几何差异的点集
ST_Dimension()几何纬度
ST_Disjoint()一个几何是否与另一个不相连
ST_Distance()一个几何到另一个的距离
ST_Distance_Sphere()地面上两个几何的最近距离
ST_EndPoint()LineString的终点
ST_Envelope()返回几何最小包围盒
ST_Equals()两个几何是否相同
ST_ExteriorRing()范围Polygon的外部圈
ST_FrechetDistance()返回两个几何的弗雷歇距离(8.0.23后支持)
ST_GeoHash()产生地理哈希值
(((

ST_GeomCollFromText(),

ST_GeometryCollectionFromText(),

ST_GeomCollFromTxt()

)))|通过WKT返回几何集合

(((

ST_GeomCollFromWKB(),

ST_GeometryCollectionFromWKB()

)))|通过WKB返回几何几何

ST_GeometryN()返回几何集合上的第n个几何
ST_GeometryType()返回几何类型的名称
ST_GeomFromGeoJSON()通过GeoJSON产生几何
(((

ST_GeomFromText(),

ST_GeometryFromText()

)))|通过WKT产生几何

(((

ST_GeomFromWKB(),

ST_GeometryFromWKB()

)))|通过WKB产生几何

ST_HausdorffDistance()两个几何之间的豪斯多夫距离(8.0.23后支持)
ST_InteriorRingN()返回Polygon的第n个孔
ST_Intersection()返回两个几何相交的点集
ST_Intersects()一个几何与另一个是否相交
ST_IsClosed()一个几何是否闭合而且简单
ST_IsEmpty()一个几何是否是空集
ST_IsSimple()一个几何是否简单
ST_IsValid()一个几何是否有效
ST_LatFromGeoHash()从地理哈希值获取纬度
ST_Latitude()返回点的纬度
ST_Length()返回线的长度
(((

ST_LineFromText(),

ST_LineStringFromText()

)))|通过WKT创建LineString

(((

ST_LineFromWKB(),

ST_LineStringFromWKB()

)))|通过WKB创建线

ST_LineInterpolatePoint()沿LineString给定百分比的点(8.0.24后支持)
ST_LineInterpolatePoints()沿LineString给定百分比的点集(8.0.24后支持)
ST_LongFromGeoHash()返回地理哈希值的经度
ST_Longitude()返回点的经度(8.0.12后支持)
ST_MakeEnvelope()通过两个点创建信封
(((

ST_MLineFromText(),

ST_MultiLineStringFromText()

)))|通过WKT创建多线

(((

ST_MLineFromWKB(),

ST_MultiLineStringFromWKB()

)))|通过WKB创建多线

(((

ST_MPointFromText(),

ST_MultiPointFromText()

)))|通过WKT创建多点

(((

ST_MPointFromWKB(),

ST_MultiPointFromWKB()

)))|通过WKB创建多点

(((

ST_MPolyFromText(),

ST_MultiPolygonFromText()

)))|通过WKT创建多面

(((

ST_MPolyFromWKB(),

ST_MultiPolygonFromWKB()

)))|通过WKB创建多面

ST_NumGeometries()返回几何集合中几何的数量
(((

ST_NumInteriorRing(),

ST_NumInteriorRings()

)))|返回面中孔的数量

ST_NumPoints()返回线中孔的数量
ST_Overlaps()一个几何是否与另一个重写
ST_PointAtDistance()沿着LineString给定距离的点(8.0.24后支持)
ST_PointFromGeoHash()计算点的地理哈希值
ST_PointFromText()通过WKT创建点
ST_PointFromWKB()通过WKB创建点
ST_PointN()返回线的第n个点
(((

ST_PolyFromText(),

ST_PolygonFromText()

)))|通过WKT创建面

(((

ST_PolyFromWKB(),

ST_PolygonFromWKB()

)))|通过WKB创建面

ST_Simplify()简化几何
ST_SRID()返回几何的SRID
ST_StartPoint()返回线的起始点
ST_SwapXY()返回x和y交换的值
ST_SymDifference()返回两个几何对称不同的点集
ST_Touches()两个几何是否接触
ST_Transform()转换几何坐标(8.0.13)
ST_Union()返回两个几何合并后的点集
ST_Validate()判断几何是否有效
ST_Within()一个几何是否在另一个几何内部
ST_X()返回点的X值
ST_Y()返回点的Y值

几何格式转换

//参考:《refman-8.0-en.pdf》12.17.6几何格式转换函数。//

空间索引

//参考:《refman-8.0-en.pdf》8.3.3空间索引优化。//

//参考:《refman-8.0-en.pdf》13.1.15创建索引。//

空间参考系表

//参考:《refman-8.0-en.pdf》13.1.19创建空间参考系。//

//参考:《refman-8.0-en.pdf》13.1.31删除空间参考系。//

//参考:《refman-8.0-en.pdf》26.3.36空间索引优化。//

INFORMATION_SCHEMA ST_SPATIAL_REFERENCE_SYSTEMS表。