空间数据库课程设计报告第八章.docx
- 文档编号:728090
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:30
- 大小:453.42KB
空间数据库课程设计报告第八章.docx
《空间数据库课程设计报告第八章.docx》由会员分享,可在线阅读,更多相关《空间数据库课程设计报告第八章.docx(30页珍藏版)》请在冰点文库上搜索。
空间数据库课程设计报告第八章
第8章空间索引和操作符
一、空间索引
(一)建立索引之前为空间层插入元数据
空间层的空间元数据是插入在USER_SDO_GEOM_METADATA视图中程序8-3列出了该视图的所有域:
程序8-3
DESCRIBEUSER_SDO_GEOM_METADATA;
程序8-4对这些域进行了赋值:
程序8-4
INSERTINTOuser_sdo_geom_metadata
(table_name,column_name,srid,diminfo)
VALUES
(
'CUSTOMERS',--TABLE_NAME
'LOCATION',--COLUMN_NAME
8307,--SRIDspecifyingageodeticcoordinatesystem
SDO_DIM_ARRAY--DIMINFOattributeforstoringdimensionbounds,tolerance
(
SDO_DIM_ELEMENT
(
'LONGITUDE',--DIMENSIONNAMEforfirstdimension
-180,--SDO_LBforthedimension:
-180degrees
180,--SDO_UBforthedimension:
180degrees
0.5--Toleranceof0.5meters(not0.5degrees:
geodeticSRID)
),
SDO_DIM_ELEMENT
(
'LATITUDE',--DIMENSIONNAMEforseconddimension
-90,--SDO_LBforthedimension:
-90degrees
90,--SDO_UBforthedimension:
90degrees
0.5--Toleranceof0.5meters(not0.5degrees:
geodeticSRID)
)
)
);
(二)创建空间索引
完成元数据的插入后,就可以创建空间索引了。
可是如果你以前创建索引时失败了,首相必须删除失败的索引,如程序8-5:
程序8-5
DROPINDEXcustomers_sidx;
删除以前的空间索引后,就可以创建新的索引了,如程序8-6:
程序8-6
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX;
(三)空间索引概念
在内部,spatial_index是用R_tree索引实现的。
空间索引的元数据存储在视图USER_SDO_INDEXE_METADATA中。
本视图存储空间索引名称,存放索引的表,R_tree索引的根ROWID,R_tree节点的分支因子或fanout(子树的最大个数),以及其他相关参数。
通过这个视图,可以确定给定空间索引对应的空间索引表。
程序8-7通过查询USER_SDO_INDEXE_METADATA视图的SDO_INDEXE_TABLE列,可以得到空间索引表:
程序8-7
SELECTSDO_INDEX_TABLEFROMUSER_SDO_INDEX_INFO
WHERETABLE_NAME='CUSTOMERS'ANDCOLUMN_NAME='LOCATION';
二、空间索引参数
(一)参数
(1)TABLESPACE参数。
通过这个参数,可以指定那个空间来存储空间索引表,程序8-9给出了一个示例,TABLESPACE=TBS_3会将空间索引表存储在表空间TBS_3中:
程序8-9
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('TABLESPACE=TBS_3');
除了TABLESPACE参数之外,你还可以指定另外两个参数INITLE和NEXT,如程序8-10:
程序8-10
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('TABLESPACE=TBS_3NEXT=5KINITIAL=10K');
(2)WORK_TABLESPACE参数。
在索引的创建过程中,R_tree索引会在整个数据集上执行排序操作,因此会产生一些工作表,使用WORK_TABLESPACE参数来为这些工作表指定一个单独的表空间,如程序8-11所示:
程序8-11
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('WORK_TABLESPACE=SYSAUX');
(3)LAYER_GTYPE参数。
通过这个参数,可以指定customers表的locationl列的几何数据为特定类型几何体,如程序8-12所示,指定LAYER_POINT来表示customers表只含有点型数据:
程序8-12
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('LAYER_GTYPE=POINT');
(4)SDO_INDX_DIMS参数。
该参数指定spatial_index的维数,默认值为2.程序8-13说明了如何显式地将索引维数设为2:
程序8-13
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('SDO_INDX_DIMS=2');
(5)SDO_DML_BATCH_SIZE参数。
这个参数用于指定一个事务中批量插入、删除、更新时的批量大小。
如果没有被明确的指定,该参数被内部设为1000.
(6)SDO_LVEL参数。
除了R_tree外,还可以通过在PARAMETERS子句中指定SDO_LEVEL参数来创建一个四分树索引。
如程序8-15:
程序8-15
CREATEINDEXcustomers_sidxONcustomers(location)
INDEXTYPEISMDSYS.SPATIAL_INDEX
PARAMETERS('SDO_LEVEL=8');
(二)USER_SDO_INDEX_METADA视图
如程序8-16,创建一个空间索引后,就可以检查该索引的SDO_DML_BATCH_SIZE值:
程序8-16
SELECTSDO_DML_BATCH_SIZEFROMUSER_SDO_INDEX_METADATA
WHERESDO_INDEX_NAME='CUSTOMERS_SIDX';
(三)空间索引大小需求
可以运行程序8-17中的实用函数来粗略的估计一个R_tree空间索引表的大小:
程序8-17
SELECTsdo_tune.estimate_rtree_index_size
(
'SPATIAL',--schemaname
'CUSTOMERS',--tablename
'LOCATION'--columnnameonwhichthespatialindexistobebuilt
)sz
FROMdual;
三、空间操作符
(一)空间操作符的语法
空间操作符的语法如程序8-18所示:
程序8-18
{
table_geometryINSDO_GEOMETRY(orST_GEOMETRY),
query_geometryINSDO_GEOMETRY(orST_GEOMETRY)
[,parameter_stringINVARCHAR2
[,tagINNUMBER]]
)
=’TURE’
在程序8-18中,如下叙述为真:
(1)table_geometry是操作符作用的表的SDO_GEOMETRY列。
(2)query_geometry是查询位置。
(3)parameter_string指定某空间操作符特有的参数。
(4)tag指定了一个在某些空间操作符中专用的数字。
(二)空间操作符的语义
程序8-19展示了第一个在WHERE子句中使用SDO_GEOMETRY_DISTANCE操作符的空间查询,第一个变量指定了在customers表中被索引的列名,第二个变量指定一个查询位置,第三个变量指定操作符特定的参数,返回在查询位置0.5英里范围内的所有客户:
程序8-19
SELECTCOUNT(*)
FROMbranchesb,customersc
WHEREb.id=1
ANDSDO_WITHIN_DISTANCE
(c.location,b.location,'DISTANCE=0.5UNIT=MILE')='TRUE';
(三)空间操作符的计算
空间操作符的计算是通过一个涉及空间索引的两部过滤机制来完成的。
一个空间操作符首先是通过空间索引来计算的,这被称为初级过滤。
然后使用geometryengine处理这个候选行集,从而返回符合指定操作符的正确行集,这就是二级过滤。
四、深入理解空间操作符
(一)SDO_WITHIN_DISTANCE操作符
给定一个位置集,SDO_WITHIN_DISTANCE操作符将从中返回在一个查询位置指定距离范围内的所有位置。
程序8-20演示了SDO_WITHIN_DISTANCE操作符的用法,它找出了指定的竞争对手商店(storeid=1)周围0.25英里范围内的所有客户:
程序8-20
SELECTct.id,ct.name
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDSDO_WITHIN_DISTANCE
(ct.location,comp.location,'DISTANCE=0.25UNIT=MILE')='TRUE'ORDERBYct.id;
使用空间函数SDO_GEOM.SDO_DISTANCE可以得到这些返回的客户与指定商店之间的距离,如程序8-21:
程序8-21
coldistformat999
SELECTct.id,ct.name,
SDO_GEOM.SDO_DISTANCE(ct.location,comp.location,0.5,'UNIT=YARD')dist
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDSDO_WITHIN_DISTANCE
(ct.location,comp.location,'DISTANCE=0.25UNIT=MILE')='TRUE'
ORDERBYct.id;
(2)SDO_NN操作符
给定一个位置集,SDO_NN操作符将按其与查询位置的距离顺序来返回数据。
程序8-25展示了如何利用SDO_NN操作符在商业应用中进行邻近分析:
程序8-25
SELECTct.id,ct.name
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDSDO_NN(ct.location,comp.location)='TRUE';
程序8-25中的查询返回所有3173个客户的id,但一般情况下,我们只对最近的几个客户感兴趣,使用ROWNUM<=N,可以返回最近的N个客户。
程序8-26给出了N为5的SQL语句:
程序8-26
SELECTct.id,ct.name,ct.customer_grade
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDSDO_NN(ct.location,comp.location)='TRUE'
ANDROWNUM<=5
ORDERBYct.id;
如果只想返回5个最近的GOLD客户而不是最近的5个任何客户,可以在WHERE子句中使用customer_grade='GOLD'谓词,如程序8-27:
程序8=27
SELECTct.id,ct.name,ct.customer_grade
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDct.customer_grade='GOLD'
ANDSDO_NN(ct.location,comp.location)='TRUE'
ANDROWNUM<=5
ORDERBYct.id;
(3)用于空间相互作用(关系)的操作符
程序8-36说明了如何使用SDO_GEOM.SDO_BUFFER函数在分店和竞争对手周围0.25英里构建缓冲区:
程序8-36
CREATETABLECOMPETITORS_SALES_REGIONSAS
SELECTid,name,SDO_GEOM.SDO_BUFFER
(cmp.location,0.25,0.5,'UNIT=MILEARC_TOLERANCE=0.005')geom
FROMcompetitorscmp;
CREATETABLESALES_REGIONSAS
SELECTid,name,SDO_GEOM.SDO_BUFFER
(b.location,0.25,0.5,'UNIT=MILEARC_TOLERANCE=0.005')geom
FROMbranchesb;
程序8-37给出了在这些表上创建空间索引的SQL语句:
程序8-37
INSERTINTOUSER_SDO_GEOM_METADATA
SELECT'SALES_REGIONS','GEOM',DIMINFO,SRID
FROMUSER_SDO_GEOM_METADATA
WHERETABLE_NAME='BRANCHES';
--MetadataforCompetitors_regionstable:
--copiedfromthemetadataforBranchestable
INSERTINTOUSER_SDO_GEOM_METADATA
SELECT'COMPETITORS_SALES_REGIONS','GEOM',DIMINFO,SRID
FROMUSER_SDO_GEOM_METADATA
WHERETABLE_NAME='COMPETITORS';
--Index-creationforSales_regionstable
CREATEINDEXsr_sidxONsales_regions(geom)
INDEXTYPEISMDSYS.SPATIAL_INDEX;
--Index-creationforCompetitors_sales_regionstable
CREATEINDEXcr_sidxONcompetitors_sales_regions(geom)
INDEXTYPEISMDSYS.SPATIAL_INDEX;
程序8-38给出了SDO_FILTER操作符的用法,它找出在竞争对手影响区域内的所有客户:
程序8-38
SELECTct.id,ct.name
FROMcompetitors_regionscomp,customersct
WHEREcomp.id=1
ANDSDO_FILTER(ct.location,comp.geom)='TRUE'
ORDERBYct.id;
用SDO_RELATE操作符进行客户分析,通过使用掩码ANYINTERACT,我们将找出每个竞争对手的缓冲区内部或边界上的所有客户,如程序8-40:
程序8-40
SELECTct.id,ct.name
FROMcompetitors_sales_regionscomp,customersct
WHEREcomp.id=1
ANDSDO_RELATE(ct.location,comp.geom,'MASK=ANYINTERACT')='TRUE'
ORDERBYct.id;
检查有多少竞争对手的区域与D.C区域相交,如程序8-42:
程序8-42
SELECTCOUNT(*)
FROMus_statesst,competitors_sales_regionscomp
WHEREst.state_abrv='DC'
ANDSDO_RELATE(comp.geom,st.geom,'MASK=ANYINTERACT')='TRUE';
并不是所有上面的竞争对手的销售区域都在D.C区内部。
为了获得销售区域完全在D.C区域内的竞争对手,必须使用带有INSIDE关系的SDO_RELATE操作符,如程序8-43:
程序8-43
SELECTCOUNT(*)
FROMus_statesst,competitors_sales_regionscomp
WHEREst.state_abrv='DC'
ANDSDO_RELATE(comp.geom,st.geom,'MASK=INSIDE')='TRUE';
对于那些影响范围超出D.C区域但仍然与其重叠的竞争对手,应该使用带有OVERLAPBDYINTERSECT关系的SDO_RELATE操作符,如程序8-44:
程序8-44
SELECTCOUNT(*)
FROMus_statesst,competitors_sales_regionscomp
WHEREst.state_abrv='DC'
ANDSDO_RELATE(comp.geom,st.geom,'MASK=OVERLAPBDYINTERSECT')='TRUE';
程序8-45可以确定与给定的销售区域相交的所有销售区域:
程序8-45
SELECTsr1.id
FROMsales_regionssr2,sales_regionssr1
WHEREsr2.id=51
ANDsr1.id<>51
ANDSDO_RELATE(sr1.geom,sr2.geom,'MASK=ANYINTERACT')='TRUE';
要看有多少销售区域与查询区域重叠,这涉及在SDO_RELATE操作符的parameter_string中指定两个掩码,如程序8-46:
程序8-46
SELECTsr1.id
FROMsales_regionssr2,sales_regionssr1
WHEREsr2.id=51
ANDsr1.id<>51
ANDSDO_RELATE
(sr1.geom,sr2.geom,'MASK=OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT')='TRUE';
程序8-45中返回的9个销售区域中只有8个是重叠的,也就是说,其它与销售区域相交的区域,实际上是接触的,可以用程序8-47来验证:
程序8-47
SELECTa.id
FROMsales_regionsb,sales_regionsa
WHEREb.id=51
ANDa.id<>51
ANDSDO_RELATE(a.geom,b.geom,'MASK=TOUCH')='TRUE';
(4)空间操作符的Hint
INDEXE/NO_INDEXHint将表的别名作为第一个参数,索引名作为第二个参数,程序8-52将正确执行并返回按距离排好序的客户。
程序8-52
SELECT/*+NO_INDEX(ctcust_grade)INDEX(ctcustomers_sidx)*/
ct.id,ct.customer_grade,SDO_NN_DISTANCE
(1)distFROM
competitorscomp,customersct
WHEREcomp.id=1
ANDct.customer_grade='GOLD'
ANDSDO_NN(ct.location,comp.location,'SDO_BATCH_SIZE=100',1)='TRUE'
ANDROWNUM<=5
ORDERBYct.id;
如果SQL语句中有多个表,那么优化器有可能不使用空间索引,如果想使用就必须将使用空间索引的表作为内部表,可以将该表指定为SELECT语句中FROM子句的最后一个表,同时使用ORDEREDHint,如程序8-53:
程序8-53
SELECT/*+ORDERED*/ct.id,ct.name
FROMcompetitorscomp,customersct
WHEREcomp.id=1
ANDSDO_WITHIN_DISTANCE
(ct.location,comp.location,'DISTANCE=0.25UNIT=MILE')='TRUE'
ORDERBYct.id;
5、空间索引的高级特性
(1)基于函数的空间索引
Oracle允许在作用于同一张表的一列或多列的函数上创建B_tree索引。
需要围绕SDO_GCDR.GEOCODE_AS_GEOMETRY创建一个DETERMINISTIC函数gcdr_geometry,如程序8-54:
程序8-54
CREATEorREPLACEFUNCTIONgcdr_geometry(
street_numbervarchar2,
street_namevarchar2,
cityvarchar2,
statevarchar2,
postal_codevarchar2
)
RETURNMDSYS.SDO_GEOMETRYDETERMINISTICis
BEGIN
RETURN(
sdo_gcdr.geocode_as_geometry(
'SPATIAL',
sdo_keywordarray(
street_number||''||street_name,
city||''||state||''||postal_code
),
'US')
);
END;
/
程序8-55给出的SQL语句调用了两次gcdr_geometry函数,如果它被声明为DETERMINISTIC,那么优化器将只对其评估一次。
程序8-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 空间 数据库 课程设计 报告 第八