笔记:MySQL Spatial Extensions
来源:互联网 发布:js将数组转换成json 编辑:程序博客网 时间:2024/05/21 04:21
最好的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:
CREATE TABLE address (
address CHAR(80) NOT NULL,
address_loc POINT NOT NULL,
PRIMARY KEY(address),
SPATIAL KEY(address_loc)
);
其中,address_loc就是一个point类型,说明address_loc是一个点。
插入一个点:
INSERT INTO address VALUES('Foobar street 12', GeomFromText('POINT(2671 2500)'));
读取一个点:
select AsText(address_loc) from address …
一个比较麻烦的问题是,如何计算两个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。
Reference:
【1】官方文档: http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html
【2】官方文档: http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html
- 笔记:MySQL Spatial Extensions
- 笔记:MySQL Spatial Extensions
- MySQL Spatial Extensions 地理信息
- App Extensions学习笔记
- App Extensions学习笔记
- 关于hibernate支持mysql-spatial
- 【论文笔记】Spatial Transformer Networks
- 【论文笔记】Spatial Transformer Networks
- Spatial Transformer Networks 论文笔记
- Spatial Transformer Network学习笔记
- Swift3.0学习笔记-Extensions
- Swift3.0学习笔记-Extensions
- Extensions
- 【CS231n笔记】08 Spatial Localization and Detection
- WWDC2014之App Extensions学习笔记
- WWDC2014之App Extensions学习笔记
- WWDC2014之App Extensions学习笔记
- (转)WWDC2014之App Extensions学习笔记
- hibernate 数据源配置
- J2EE常用资源管理方式总结
- 快要疯了,iPad里面的navigation好怪异[终于解决了,不太会用popover的同学可以参考]
- 创建悬浮对话框和触摸任何位置都可以关闭的对话框
- 战胜Facebook的方法
- 笔记:MySQL Spatial Extensions
- UIImagePickerController Save to Disk then Load to UIImageView
- PARTITION RANGE SUBQUERY子查询消除
- Java学习从入门到精通[原创]自我感觉特别好
- iPhone - UIImagePickerController -> save the image to app folder
- IE8不能运行JavaScript
- Get iPhone Status Bar Height
- Excel表数据导入Sql Server数据库中
- 恢复或者隐藏IE地址栏