Oracle Spatial空间操作符

阅读更多
Oracle Spatial支持许多空间操作符以进行空间邻近分析,这些空间操作符类似于关系操作符(<、>和=),可以在SQL的WHERE子句中使用。
与几何操作不同的是操作符进行空间操作的对象必须有空间索引才行,也就是说空间操作符是与空间索引绑定的(具体来讲:至少空间操作符的第一个参数——table_geometry必须有空间索引)。

空间操作符的语法

(
  table_geometry      IN SDO_GEOMETRY (或者 ST_GEOMETRY),
  query_geometry      IN SDO_GEOMETRY (或者 ST_GEOMETRY),
  [, parameter_string IN VARCHAR2
     [, tag           IN NUMBER ]]
)
= 'TRUE'

table_geometry: 空间操作符要运用到的表几何体数据列;
query_geometry: 查询位置,可以是另一个表的几何体数据列,也可以是一个绑定的变量,或者是一个动态创建的几何体对象;
parameter_string: 指定特定的空间操作符参数,有些操作符中是可选的;
tag:在某些特定空间操作符上需要的数值,相关参数只能在parameter_string参数中指定。

此外还有些限定:
1. table_geometry列必须已经空间索引列;
2. 操作符应该总是等于字符串'TRUE',所以,别考虑FALSE了;
3. 要操作的数据库表的列要么是oracle原生的SDO_GEOMETRY类型,要么是ST_GEOMETRY类型及其子类型(例如ST_POINT, ST_LINESTRING或者ST_POLYGON)


空间操作符的语义
当在SQL语句中使用空间操作符时,Oracle会找出那些空间操作符计算为TRUE的数据行。想想id>=20
一个例子:
SELECT COUNT(*)
FROM branches b, customers c
WHERE  b.id=1
AND SDO_WITHIN_DISTANCE
(c.location, b.location, 'DISTANCE=0.5 UNIT=MILE') = 'TRUE';


空间操作符如何计算
因为空间操作符依赖于空间索引,实际上大多数情况下,计算是一种两阶段过滤机制。
Oracle Spatial空间操作符_第1张图片
如图所示,空间操作符首先是要空间索引进行第一次计算,即primary filter。


空间操作符分类
按邻近分析的类型可分为:
1. 位置查询:从指定查询位置找出所有特定距离内的所有数据,即within distance操作符(SDO_WITHIN_DISTANCE);

2. 邻近查询:找出指定查询位置附近最近的那些邻居,即最近邻居(nearest-neighbor)操作符(SDO_NN);

3. 相交查询:找出与指定查询位置相交的所有邻居(Find neighbors that interact with or relate to a query location):主要操作符是SDO_RELATE,更简单的有SDO_FILTER(只是MBR的计算,因此也不需要Geometry Engine操作),此类操作符主要用于区域分析。此外还有对SDO_RELATE的简化版,如SDO_ANYINTERACT, SDO_CONTAINS, SDO_COVERS, SDO_COVEREDBY, SDO_EQUAL, SDO_INSIDE, SDO_ON, SDO_OVERLAPS, 和SDO_TOUCH
相交的分类模型,一个几何体由三部分组成:边界、内部和外部,
对于点:边界就是一个边界点
对于线:边界就是首尾两端的端点,
对于多边形:边界就是边界环 ring
Oracle Spatial空间操作符_第2张图片
SDO_RELATE操作符中定义的几种相交类型,Q即为查询几何体,A对应着数据表中的几何体字段。
这些相交类型分类是根据几何体之间内部和边界的情况进行分类的


空间连接(Spatial Joins)
对于两个都要空间信息的表进行空间操作符操作是很耗时的,例如:
SELECT COUNT(DISTINCT ct.id)
FROM competitors comp, customers ct
WHERE SDO_WITHIN_DISTANCE(ct.location, comp.location, 'DISTANCE=200 UNIT=METER') = 'TRUE';

查询结果1145,查询时间为6.11秒。

使用SDO_JOIN可以提高这类查询的效率。
SDO_JOIN
(
table1                    IN VARCHAR2,
col1                      IN VARCHAR2,
table2                    IN VARCHAR2,
col2                      IN VARCHAR2
[, parameter_string       IN VARCHAR2    DEFAULT NULL
[, preserve_join_order    IN NUMBER      DEFAULT 0
[, table1_partition       IN VARCHAR2    DEFAULT NULL,
[ , table2_partition      IN VARCHAR2    DEFAULT NULL]]]]
)
RETURNS SDO_ROWIDSET

返回值是一组ROWID对()的集合。
前面的查询改为:
SELECT COUNT(DISTINCT ct.id)
FROM competitors comp, customers ct,
     TABLE(
         SDO_JOIN(
             'competitors', 'location',
             'customers', 'location',
             'DISTANCE=200 UNIT=METER'
         )
     ) jn
WHERE ct.rowid=jn.rowid2 AND comp.rowid = jn.rowid1;

同样的结果,查询速度缩短到1.343秒。
  • Oracle Spatial空间操作符_第3张图片
  • 大小: 30.2 KB
  • Oracle Spatial空间操作符_第4张图片
  • 大小: 26.5 KB
  • 查看图片附件

你可能感兴趣的:(Oracle,SQL)