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. 认识Agile,Scrum和DevOps

    If everything's under control you are going too slow. 当今的开发,要求faster and faster.所以我们要Agile,become Ag ...

  2. 在Chrome Console中加载jQuery

    var jq = document.createElement('script'); jq.src = "//ajax.googleapis.com/ajax/libs/jquery/1/j ...

  3. (转载)OC学习篇之---Foundation框架中的NSString对象和NSMutableString对象

    在之前的一篇文章中我们说到了Foundation框架中的NSObject对象,那么今天在在来继续看一下Foundation框架中的常用对象:NSString和NSMutableString. 在OC中 ...

  4. python实现不可修改的常量

    因为种种原因,Python并未提供如C/C++/Java一样的const修饰符,换言之,python中没有常量,至少截止2015年年末,还没有这个打算.Python程序一般通过约定俗成的变量名全大写的 ...

  5. [Android][Audio] audio_policy.conf文件分析

    不同的Android产品在音频的设计上通常是存在差异的,而这些差异可以同过Audio的配置文件audio_policy.conf来获得.在Android系统中音频配置文件存放路径有两处,存放地址可以从 ...

  6. 利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引)

    利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引) ##应用情景 项目中有大量的SQL,尤其是涉及到统计报表时,表关联比较多,当初开发建表时也没搞好索引关联的,上线后 ...

  7. extjs 学习笔记(二)

    EXTJS实用开发指南 1. 要使用ExtJS 框架的页面中一般包括下面几句: <link rel="stylesheet" type="text/css" ...

  8. easyui dialog遮罩层

    当dialog在一个iframe里时,此dialog的遮罩层也会只覆盖这个iframe,要想覆盖整个页面,就把dialog写到最外层的父页面中去,此时dialog的遮罩层会自动覆盖整个页面,若需要从子 ...

  9. pd虚拟机死机怎么解决

    最近在mac上使用pd虚拟机装win使用,今天发现pd中的win7虚拟机死机了,无论怎么点都没用,通过点击操作-关闭也不行,重启电脑也不行,后来找到一种办法可以重启虚拟机. 1.先通过菜单中止虚拟机, ...

  10. codeforces 601A The Two Routes(最短路 flody)

    A. The Two Routes time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...