VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 数据库 > MySQL >
  • Mysql空间数据&空间索引(spatial)(4)

ST_GeomFromText() 来创建几何值。你可以使用type-specific(类型定义)函数//这里留有疑义,下面的例子和前面的相同都是使用ST_GeomFromText() 但是我感觉更像是要使用类似POINT() 函数:

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));

一个应用程序想要在查询服务器的时候使用WKB 表示几何数值.下面有几个方法实现这个需求。例如

  • 插入一个POINT(1 1)使用二进制语法:

    mysql> INSERT INTO geom VALUES
        -> (ST_GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
    
  • 一个ODBC应用可以发送一个WKB表达式,并把他绑定到一个占位符上,使用BLOB 类型:

    INSERT INTO geom VALUES (ST_GeomFromWKB(?))
    

    其他程序接口可能支持类似的占位符机制

  • C 语言中,你可以使用 mysql_real_escape_string() 跳过一个二进制数值,包含结果到一个查询字符串中

 

12.5.3.4 读取Fetching Spatial Data

Geometry数值存储在表格中可以读取到内部格式,你可以转换成WKT或者WKB格式

  • 读取空间数据到内部格式:

    读出来的内部格式在表和表之间传递很有用

    CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
    
  • 读取到WKT格式:

     ST_AsText() 方法将内部格式转换成WKT字符串

    SELECT ST_AsText(g) FROM geom;
    
  • 读取到WKB格式:

    ST_AsBinary() 方法将内部格式转换到一个 包含WKB值得 BLOB

    SELECT ST_AsBinary(g) FROM geom;
    

12.5.3.5 优化空间分析Optimizing Spatial Analysis

对于MyISAM and (as of MySQL 5.7.5) InnoDB tables,在包含空间数据的列中执行搜索操作 可以通过使用SPATIAL indexes(空间索引)进行优化. 典型的操作是:

  • Point 搜索:搜索包含一个给定的点的所有对象

  • 地区搜索:搜索与给定区域重叠的所有对象

MySQL使用 R-Trees with quadratic splitting(二次分割) 来创建空间索引到空间列上.一个空间索引是使用minimum bounding rectangle (最小外包矩形MBR)建立的.对于大多数几何体来说, the MBR 是一个最小的可以包含这个几何体的矩形.对于一个水平或者垂直的linestring, the MBR是一个变化的linestring内部 的矩形。对于一个point, the MBR是一个变化的点内的矩形.

同样也可能创建普通索引到空间列上,在一个非空间索引, you must declare a prefix for any spatial column except for POINT columns.

MyISAM and InnoDB 都支持 SPATIAL and non-SPATIAL indexes.

 
12.5.3.6 Creating Spatial Indexes
 
For MyISAM and (as of MySQL 5.7.5) InnoDB tables, MySQL可以使用类似普通索引的语法创建空间索引, 但是需要使用 SPATIAL关键字.索引项必须是非空。下面的例子展示如何创建空间索引
 
    With CREATE TABLE:
 
    CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;
 
    With ALTER TABLE:
 
   ALTER TABLE geom ADD SPATIAL INDEX(g);
 
    With CREATE INDEX:
 
    CREATE SPATIAL INDEX sp_index ON geom (g);
 
SPATIAL INDEX 创建了一个R-tree 索引。对于支持非空间索引的存储引擎,引擎创建一个B-tree索引. B-tree 索引在准确值查找上是很有用的,但在范围扫描就不一样了。
 
 
删除spatial indexes, use ALTER TABLE or DROP INDEX:
 
    With ALTER TABLE:
 
    ALTER TABLE geom DROP INDEX g;
 
    With DROP INDEX:
 
    DROP INDEX sp_index ON geom;
 
Example: 假设一个 table geom包含超过32,000 geometries,存放在类型为GEOMETRY 的 g列 .table有一个AUTO_INCREMENT列fid做为对象ID。
 
mysql> DESCRIBE geom;
+-------+----------+------+-----+---------+----------------+
 | Field   |   Type     |  Null |  Key | Default | Extra               |
+-------+----------+------+-----+---------+----------------+
 | fid     | int(11)     |          | PRI  | NULL     | auto_increment |
 | g       | geometry |          |       |            |                      |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
 
mysql> SELECT COUNT(*) FROM geom;
+----------+
| count(*)   |
+----------+
|    32376   |
+----------+
1 row in set (0.00 sec)
 
添加一个空间索引到g。
 
mysql> ALTER TABLE geom ADD SPATIAL INDEX(g) ENGINE=MyISAM;
Query OK, 32376 rows affected (4.05 sec)
Records: 32376  Duplicates: 0  Warnings: 0
 

12.5.3.7 Using Spatial Indexes

 
优化器调查是否可用空间索引参与搜索查询,这个查询在WHERE子句中使用函数如MBRContains()或MBRWithin()。以下查询找到所有对象在给定的矩形:

 

 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
               31000 15000,
               31000 16000,
               30000 16000,
               30000 15000))';
mysql> SELECT fid,ST_AsText(g) FROM geom WHERE
    -> MBRContains(ST_GeomFromText(@poly),g);
+-----+---------------------------------------------------------------+
| fid | ST_AsText(g)                                          |
+-----+---------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
+-----+---------------------------------------------------------------+
20 rows in set (0.00 sec)
 
使用EXPLAIN 检查这个查询被执行的方式
 
mysql> SET @poly =
    -> 'Polygon((30000 15000,
               31000 15000,
               31000 16000,
               30000 16000,