http://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html

http://mysqlserverteam.com/mysql-5-7-and-gis-an-example/

最好的Spatial Database(空间数据库)当然是Oracle家的,可惜没用过。最好的开源的Spatial Database一般公认是PostGIS,以前用过一阵子,安装特别麻烦,不过各种功能很齐全。前段时间尝试了一下MySQL的spatial extensions,下面记录了一些使用心得:

1. MySQL Spatial Extensions(后面简称MySQL Spatial)功能不够完全。至少和PostGIS相比是这样的,它只支持了openGIS(一个标准)的一个子集,包涵有限的几种空间数据类型(比如Point,LineString,Polygon等),支持的函数也很少,比如,连计算两个点的distance函数都没有...
2. MySQL Spatial的安装配置非常的简单。其实,它根本不需要安装。默认的MySQL配置就能够使用这些空间数据类型。这和PostGIS很不一样,PostGIS是需要在PostgreSQL上再安装一个扩展包。
3. 不同的存储引擎有差别。MyISAM和InnoDB都支持spatial extensions,但差别在于:如果使用MyISAM,可以建立spatial index,而InnoDB是不支持的。这点差别在某些场景下很关键,后面会再详细说说spatial index。
4. POINT的使用。点是最基本也是最常用的一种空间数据类型。MySQL Spatial中用POINT表示点,比如,可以创建一个table:

mysql 5.7

CREATE TABLE address (
address CHAR(80) NOT NULL,
address_loc POINT NOT NULL,
PRIMARY KEY(address),
SPATIAL KEY(address_loc)
);
show craate table address

CREATE TABLE `address` (
`address` char(80) NOT NULL,
`address_loc` point NOT NULL,
PRIMARY KEY (`address`),
SPATIAL KEY `address_loc` (`address_loc`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8'

其中,address_loc就是一个point类型,说明address_loc是一个点。

插入一个点:

INSERT INTO address VALUES('Foobar street 12', GeomFromText('POINT(2671 2500)'));
INSERT INTO address VALUES('Foobar street 13', ST_GEOMFROMTEXT ('POINT(2670 2500)'));

读取一个点:

select  AsText(address_loc)  from address;
# AsText(address_loc)
'POINT(2671 2500)'
'POINT(2670 2500)'

分离点X,Y

set @p = GeomFromText('POINT(11 0)');
select x(@p), y(@p);
# x(@p) y(@p)
     

The OpenGIS Geometry Model

The Geometry Class Hierarchy
Geometry Class
Point Class
Curve Class
LineString Class
Surface Class
Polygon Class
GeometryCollection Class
MultiPoint Class
MultiCurve Class
MultiLineString Class
MultiSurface Class
MultiPolygon Class

Supported Spatial Data Formats


Two standard spatial data formats are used to represent geometry objects in queries:

Well-Known Text (WKT) format

Well-Known Binary (WKB) format
mysql> SELECT ST_X(Point(15, 20));
+---------------------+
| ST_X(Point(15, 20)) |
+---------------------+
| 15 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT ST_Y(Point(15, 20));
+---------------------+
| ST_Y(Point(15, 20)) |
+---------------------+
| 20 |
+---------------------+
1 row in set (0.00 sec)

Fetching Spatial Data

Geometry values stored in a table can be fetched in internal format. You can also convert them to WKT or WKB format.

Fetching spatial data in internal format:

Fetching geometry values using internal format can be useful in table-to-table transfers:

CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
Fetching spatial data in WKT format: The ST_AsText() function converts a geometry from internal format to a WKT string. SELECT ST_AsText(g) FROM geom;
Fetching spatial data in WKB format: The ST_AsBinary() function converts a geometry from internal format to a BLOB containing the WKB value. SELECT ST_AsBinary(g) FROM geom;
CREATE TABLE geom (g GEOMETRY);
insert into geom select point(1,2);
SELECT ST_AsText(g) FROM geom;
SELECT ST_AsBinary(g) FROM geom;

Populating Spatial Columns


After you have created spatial columns, you can populate them with spatial data.

Values should be stored in internal geometry format, but you can convert them to that format from either Well-Known Text (WKT)
or Well-Known Binary (WKB) format. The following examples demonstrate how to insert geometry values into a table
by converting WKT values to internal geometry format: Perform the conversion directly in the INSERT statement: INSERT INTO geom VALUES (ST_GeomFromText('POINT(1 1)')); SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
Perform the conversion prior to the INSERT: SET @g = ST_GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);
The following examples insert more complex geometries into the table: 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));
The preceding examples use ST_GeomFromText() to create geometry values. You can also use type-specific functions: 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));
A client application program that wants to use WKB representations of geometry values is responsible for sending correctly formed WKB
in queries to the server. There are several ways to satisfy this requirement. For example: Inserting a POINT(1 1) value with hex literal syntax: mysql> INSERT INTO geom VALUES
-> (ST_GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
An ODBC application can send a WKB representation, binding it to a placeholder using an argument of BLOB type: INSERT INTO geom VALUES (ST_GeomFromWKB(?))
Other programming interfaces may support a similar placeholder mechanism.

一个比较麻烦的问题是,如何计算两个POINT的距离?之前说过了,MySQL Spatial不提供distance这个函数。官方指南的做法是这样的:
GLength(LineStringFromWKB(LineString(point1, point2)))
这条语句大概的意思是用两个点产生一个LineString的类型,然后调用GLength得到line的长度。
这么做,也对也不对。
对是因为它确实计算的是距离,但是,这种方法计算的是欧式空间的距离。或者简单的说,它计算的是直线距离。如果两个点是地理坐标,比如point(116.34, 39.28),想计算地理位置的距离,那么这样做肯定就不对了。正确的做法应该是使用专门计算地理位置的公式。

5. MySQL Spatial Index的使用。使用这样的语句:

ALTER TABLE address ADD SPATIAL INDEX(address_loc); 

可以在空间数据类型上创建一个spatial index,这个功能只有MyISAM才支持。Index的本质实际上是一个R-TREE,这也是最常用来作为多维数据索引的数据结构。
那么,该如何使用这个index?

举例来说,假设需要查找某个矩形区域内所有的点,一种方法是这样:
select * from address where (X(address_loc) > 116.3952) AND (X(address_loc) < 116.4052) AND (Y(address_loc) > 39.8603) AND (Y(address_loc) < 39.8703);

假设我们已经在address_loc这个column上创建了spatial index,所以上述的查询应该很快。不幸的是,这不是事实。上述的查询会扫描table内的所有数据,挨个进行计算,建立的index完全不起作用。
正确的做法是,在查询中使用一些内建的和spatial有关的函数,只有这些函数能够有效的利用到index。比如,正确的查询应该是:
select AsText(address_loc) from address where MBRContains(GeomFromText(Polygon((115.3073 40.3821, 115.3173 40.3821, 115.3173 40.4021, 115.3073 40.4021, 115.3073 40.3821))),address_loc); 
这里用到了函数MBRContains,用于判断一个point是否在指定的polygon内部。这个函数就能够很好的使用之前创建的spatial index。可以做个试验,比较之前两个查询的处理时间,你会发现,后者的速度要快很多。

总的来说,如果只需要做一些简单的GIS或者LBS的应用,MySQL提供的spatial extensions能够满足。但如果需要的功能更复杂一些,MySQL spatial extensions提供的功能可能就不够用了,需要在MySQL之上自己实现更多的逻辑,或者换成PostGIS。

MySQL Spatial Extensions 地理信息的更多相关文章

  1. Extensions for Spatial Data

    http://dev.mysql.com/worklog/task/?spm=5176.100239.blogcont4270.8.j3asa7&id=6609 前文: 这两天因为项目原因看了 ...

  2. Mysql 地区经纬度 查询

    摘要: Mysql数据库,根据地区的经纬度信息,查询附近相邻的地区 2015-03-27 修改,增加 MySQL的空间扩展(MySQL Spatial Extensions)的解决方案: MySQL的 ...

  3. mysql空间扩展 VS PostGIS

    http://www.cnblogs.com/LBSer/p/3629149.html 功能 Mysql spatial extension  PostGIS 空间索引 仅MyISAM支持R树索引,I ...

  4. 深入浅出Symfony2 - 结合MongoDB开发LBS应用

    简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在的项目也正从事相关系统的开发,我们使用的是S ...

  5. 结合MongoDB开发LBS应用

    然后列举一下需求:1.实时性要高,有频繁的更新和读取2.可按距离排序支持分页3.支持多条件筛选(一个经纬度数据还包含其他属性,比如社交系统的性别.年龄) 方案简单介绍:1.sphinx geo索引支持 ...

  6. 结合MongoDB开发LBS应用(转)

    原文链接:结合MongoDB开发LBS应用 简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在 ...

  7. MySQL开发总结(有点长..耐心看)

    一.理解MySQL基本概念 1.MySQL软件:MySQL实际上就是一软件,是一工具,是关系型数据库管理系统软件 2.MySQL数据库:就是按照数据结构来组织.存储和管理数据的仓库 3.MySQL数据 ...

  8. mysql开发总结

    一.理解MySQL基本概念 1.MySQL软件:MySQL实际上就是一软件,是一工具,是关系型数据库管理系统软件 2.MySQL数据库:就是按照数据结构来组织.存储和管理数据的仓库 3.MySQL数据 ...

  9. Mysql 和 Postgresql(PGSQL) 对比

    Mysql 和 Postgresql(PGSQL) 对比 转载自:http://www.oschina.net/question/96003_13994 PostgreSQL与MySQL比较 MySQ ...

随机推荐

  1. Winsock IO模型之select模型

    之所以称其为select模型是因为它主要是使用select函数来管理I/O的.这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字. int sele ...

  2. Python的16个“坑”

    1. 不要使用可变对象作为函数默认值 代码如下: In [1]: def append_to_list(value, def_list=[]): ...: def_list.append(value) ...

  3. HUE 安装

    1.从github网下载hue-master.zip (源代码包) 地址:https://github.com/cloudera/hue#development-prerequisites 2.安装依 ...

  4. 第三百三十二天 how can I 坚持

    今天一大早,住的这就施工了,被吵醒了.. 下午去了趟小米之家,小米5还行,黑科技不黑,哈哈. 小米5黑科技不太黑,就知道造词,整体感觉还行,就是感觉屏幕有点长,小米之家人倒是不少,还有老太太去小米之家 ...

  5. STL学习系列九:Map和multimap容器

    1.map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中key值是唯一的.集合中的元素按一定的顺 ...

  6. [转]前景检测算法--ViBe算法

    原文:http://blog.csdn.net/zouxy09/article/details/9622285 转自:http://blog.csdn.net/app_12062011/article ...

  7. HDU 4496 D-City (并查集)

    题意:给定一个图,问你每次删除一条边后有几个连通块. 析:水题,就是并查集的运用,倒着推. 代码如下: #include <cstdio> #include <string> ...

  8. 三种JDBC批量插入编程方法的比较

    JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等. 我用Mysql 5.1.5的JDBC driver 分别对三种比较常用的方法做了测试 方法一,使用PreparedStat ...

  9. oracle:自定义多行合并聚合函数

    原始表 COUNTRY CITY            -------------------- -------------- 中国 台北              中国 香港             ...

  10. 转载:Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式

    Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式 出自:http://www.cnblogs.com/top5/archive/2012/08/04/2623464.html 关 ...