SDE空间索引的内部运行机制3

ST_GEOMETRY

ST_GEOMETRY这种存储方式是从ArcSDE9.2开始支持的,但是9.2还是将SDELOB作为默认的存储方式,并没有将其作为默认的存储方式,直到ArcSDE后才开始将其作为默认的存储方式。

在详细介绍ST_GEOMETRY之前先介绍一下Oracle的复合数据类型,从Oracle 9开始,Oracle除了支持常规数据类型,如NUMBER,VARCHAR等,还开始支持复合数据类型,在Oracle中创建复合数据类型非常类似于在C++中创建类,只不过指定这个规则的是Oracle而已,我们自己可以随意的创建复合数据类型,如下面我自己创建了一个Person 的复合数据类型,这个数据类型可以存储个人信息:

CREATE TYPE person_typ AS OBJECT
(
  idno           NUMBER,
  first_name     VARCHAR2(20),
  last_name      VARCHAR2(25),
  email          VARCHAR2(25),
  phone          VARCHAR2(20),
  MAP

MEMBER FUNCTION get_idno RETURN NUMBER, 
 
 
MEMBER PROCEDURE display_details ( SELF IN OUT NOCOPY person_typ ));
 
CREATE TYPE BODY person_typ AS  MAP 

MEMBER FUNCTION get_idno RETURN NUMBER IS BEGIN RETURN idno;
END;
  
MEMBER PROCEDURE display_details ( SELF IN OUT NOCOPY person_typ ) IS
  BEGIN
-- use the PUT_LINE procedure of the DBMS_OUTPUT package to display details
 
DBMS_OUTPUT.PUT_LINE(TO_CHAR(idno) || ' ' || first_name || ' '|| last_name); DBMS_OUTPUT.PUT_LINE(email || ' ' || phone);END;
END
;
/

从上面的定义上,有成员变量,有成员方法,其格式非常类似于C++中的类。

然后可以创建一个表,其某个字段的类型可以选择person_typ,作为存储类型,如:

CREATE TABLE contacts (

contact person_typ,

contact_date DATE );

INSERT INTO contacts VALUES (

person_typ (65, 'Verna', 'Mills', 'vmills@oracle.com', '1-800-555-4412'),

'24 Jun 2003' );

ST_GEOMETRY也是一个复合存储类型,不同的是它是由ESRI公司自己定义的,用来存储空间数据的复合存储类型,它的定义也是透明的,可以使用下面的命令进行查看:

SQL> desc sde.st_geometry
 sde.st_geometry is


 NOT FINAL
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------------------
 ENTITY                                             NUMBER(38)
 NUMPTS                                             NUMBER(38)
 MINX                                               FLOAT(64)
 MINY                                               FLOAT(64)
 MAXX                                               FLOAT(64)
 MAXY                                               FLOAT(64)
 MINZ                                               FLOAT(64)
 MAXZ                                               FLOAT(64)
 MINM                                               FLOAT(64)
 MAXM                                               FLOAT(64)
 AREA                                               FLOAT(64)
 LEN                                                FLOAT(64)
 SRID                                               NUMBER(38)
 POINTS                                             BLOB
 
METHOD
------
 FINAL CONSTRUCTOR FUNCTION ST_GEOMETRY RETURNS SELF AS RESULT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 GEOM_STR                       CLOB                    IN
 SRID                           NUMBER                  IN
 
METHOD
------
 MEMBER FUNCTION ST_AREA RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_LEN RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_LENGTH RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_ENTITY RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_NUMPTS RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MINX RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MAXX RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MINY RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MAXY RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MINM RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MAXM RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MINZ RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_MAXZ RETURNS NUMBER
 
METHOD
------
 MEMBER FUNCTION ST_SRID RETURNS NUMBER
 
METHOD
------
 STATIC FUNCTION GET_RELEASE RETURNS NUMBER
 
METHOD
------
 FINAL CONSTRUCTOR FUNCTION ST_GEOMETRY RETURNS SELF AS RESULT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 X                              NUMBER                  IN
 Y                              NUMBER                  IN
 Z                              NUMBER                  IN
 M                              NUMBER                  IN
 SRID                           NUMBER                  IN

其中红色部分为该复合数据类型的成员变量,其中比较重要的环境变量为POINTS,它的类型为BLOB,该成员变量就是存储空间点串坐标的变量。

同样我们可以通过各种工具来创建包含该数据类型字段的表,如下面是我们用ArcCatalog所创建的FeatureClass cities的表结构:

Oracle数据库:

SQL> desc cities_2
 Name                                      Null     Type
 ----------------------------------------- -------- ----------------------------
 OBJECTID                                  NOT NULL NUMBER(38)
 CITY_NAME                                          NVARCHAR2(30)
 GMI_ADMIN                                          NVARCHAR2(7)
 ADMIN_NAME                                         NVARCHAR2(42)
 FIPS_CNTRY                                         NVARCHAR2(2)
 CNTRY_NAME                                         NVARCHAR2(30)
 STATUS                                             NVARCHAR2(50)
 POP_RANK                                           NUMBER(5)
 POP_CLASS                                          NVARCHAR2(22)
 PORT_ID                                            NUMBER(5)
 LABEL_FLAG                                         NUMBER(5)
 SHAPE                                              ST_GEOMETRY

DB2数据库:

 

[sde@testserver ~]$ db2 describe table sde.test
 type name      Length     Scale Nulls
------------------------------- --------- ------------------- ---------- ----- ------


OBJECTID                        SYSIBM    INTEGER 4     0 No


NAME                            SYSIBM    VARCHAR 256     0 Yes
SHAPE                           DB2GSE    ST_MULTIPOLYGON              0     0 Yes
RASTER                          SYSIBM    INTEGER 4     0 Yes

 

从该表的表结构可以看出,ST_GEOMETRY相对于的SDELOB存储方式已经将B表和F表合而为一了,以前的F表已经作为B表的一个SHAPE字段存在于B表中。

然后再介绍一下ST_GEOMETRY的索引结构:

ST_GEOMETRY存储方式的空间索引实现方式是在数据库层次上实现的,并不是在应用层次上实现的,之所以会这么说,在下面会有相应的介绍。

先介绍一下存储索引信息的位置:

和SDELOB存储方式一样,ST_GEOMETRY的具体的索引信息也是存储S表,该S表的表结构和SDELOB存储的方式一样,在此不重复介绍。

和SDELOB存储方式不同的是,它在数据库中是存在着一个相应的空间索引的定义,我将定义两个字标红的意思是该索引只是定义的一个数据库对象,其内部并不存储任何的数据,真是的索引信息是存储在S表中的,下面的数据为Cities_2表中所有的所有的索引信息:

SQL> select index_name,index_type from user_indexes where table_name='CITIES_2';
 
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
SYS_IL0000092702C00027$$       LOB
R2068_SDE_ROWID_UK             NORMAL
A1465_IX1                      DOMAIN


在列出的索引中多了一种类型为DOMAIN的索引,该索引为oracle的域索引,实际上就是自定义索引。我们接着查看一下该域索引的定义:

SQL> select dbms_metadata.get_ddl('INDEX','A1465_IX1','SDE') from dual;
 
DBMS_METADATA.GET_DDL('INDEX','A1465_IX1','SDE')
--------------------------------------------------------------------------------
  CREATE INDEX "SDE"."A1465_IX1" ON "SDE"."CITIES_2" ("SHAPE") INDEXTYPE IS "SDE"."ST_SPATIAL_INDEX" PARAMETERS ('ST_GRIDS = 4.3144346983011
T_COMMIT_ROWS = 10000  PCTFREE 0 INITRANS 4')

其中红色位置标出来的是需要注意的,

SHAPE:表示是在SHAPE字段上所建立的索引。

INDEXTYPE:索引的类型,实际上这是一个最关键的对象,在下面进行更详细的介绍

ST_GRIDS:各级网格的大小,因为该图层上我只建立了一级索引,因此在这个例子上只包括一级索引

下面接着看看SDE.ST_SPATIAL_INDEX这个对象在oracle中是如何定义的:

SQL> select dbms_metadata.get_ddl('INDEXTYPE','ST_SPATIAL_INDEX','SDE') from dual;


DBMS_METADATA.GET_DDL('INDEXTYPE','ST_SPATIAL_INDEX','SDE')                     
--------------------------------------------------------------------------------
                                                                                
  CREATE OR REPLACE INDEXTYPE "SDE"."ST_SPATIAL_INDEX" FOR                      
	 "SDE"."ST_BUFFER_INTERSECTS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY", NUMBER),
 	 "SDE"."ST_CROSSES" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),             
	 "SDE"."ST_ENVINTERSECTS" ("SDE"."ST_GEOMETRY", NUMBER, NUMBER, NUMBER, NUMBER),
 	 "SDE"."ST_ENVINTERSECTS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),        
	 "SDE"."ST_ENVINTERSECTS" ("SDE"."ST_GEOMETRY", NUMBER, NUMBER, NUMBER, NUMBER,VARCHAR2),
 	 "SDE"."ST_ENVINTERSECTS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY", VARCHAR2),
 	 "SDE"."ST_EQUALS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),    
	 "SDE"."ST_INTERSECTS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),             
	 "SDE"."ST_ORDERINGEQUALS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),         


DBMS_METADATA.GET_DDL('INDEXTYPE','ST_SPATIAL_INDEX','SDE')                     
--------------------------------------------------------------------------------
	 "SDE"."ST_OVERLAPS" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),               
	 "SDE"."ST_RELATE" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY", VARCHAR2),       
	 "SDE"."ST_TOUCHES" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY"),                
	 "SDE"."ST_WITHIN" ("SDE"."ST_GEOMETRY", "SDE"."ST_GEOMETRY")                  
	 USING "SDE"."ST_DOMAIN_METHODS"                                               
	 WITH LOCAL RANGE PARTITION                                                    
                                                                                

其中红色部分为该对象所支持所有的Operator对象,只有列在这里面的操作符对象才有可能用上索引。

绿色部分为实现网格空间索引算法的包。

还剩下最后一个问题,就是为什么说ST_GEOMETRY的空间索引是在数据库层次上实现的而不是在应用层次上实现的。大比例尺下浏览数据的时候,抓取一下后台一下相应的SQL语句如下:

*** 2010-12-16 09:41:09.632
*** ACTION
NAME:() 2010-12-16 09:41:09.631
*** MODULE


NAME:(ArcCatalog.exe) 2010-12-16 09:41:09.631
*** SERVICE NAME:(SYS$USERS) 2010-12-16 09:41:09.631
*** SESSION ID:(152.4487) 2010-12-16 09:41:09.631
=====================
PARSING IN CURSOR #25 len=69 dep=0 uid=68 oct=3 lid=68 tim=1262171552374697 hv=2558560494 ad='8ca78d78'


SELECT table_name, time_last_modified FROM SDE.sde_tables_modified
END OF STMT
EXEC #25:c=0,e=44,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1262171552374688
FETCH #25:c=0,e=52,p=0,cr=1,cu=0,mis=0,r=7,dep=0,og=1,tim=1262171552375294
=====================
PARSING IN CURSOR #46 len=288 dep=0 uid=68 oct=3 lid=68 tim=1262171552380038 hv=1466667998 ad='806b7fd8'


SELECT 1 SHAPE, CITIES_2.OBJECTID,  CITIES_2.SHAPE.points,CITIES_2.SHAPE.numpts,CITIES_2.SHAPE.entity,CITIES_2.SHAPE.minx,CITIES_2.SHAPE.miny,CITIES_2.SHAPE.maxx,CITIES_2.SHAPE.maxy,CITIES_2.rowid    FROM SDE.CITIES_2 CITIES_2 WHERE SDE.ST_EnvIntersects(CITIES_2.SHAPE,:1,:2,:3,:4) = 1
END OF STMT
EXEC #46:c=1000,e=1162,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1262171552380029
=====================
PARSING IN CURSOR #48 len=158 dep=1 uid=68 oct=3 lid=68 tim=1262171552380494 hv=4131701150 ad='806b5468'


SELECT distinct sp_id FROM SDE.S258_IDX$ WHERE gx >= :1 AND gx <= :2 AND gy >= :3 AND gy <= :4 AND minx <= :e1 AND miny <= :e2 AND maxx >= :e3 AND maxy >= :e4
END OF STMT
EXEC #48:c=0,e=117,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,tim=1262171552380485
FETCH #48:c=3000,e=2679,p=0,cr=18,cu=0,mis=0,r=100,dep=1,og=1,tim=1262171552383304
FETCH #48:c=0,e=177,p=0,cr=0,cu=0,mis=0,r=100,dep=1,og=1,tim=1262171552383632
FETCH #48:c=0,e=185,p=0,cr=0,cu=0,mis=0,r=100,dep=1,og=1,tim=1262171552383946
FETCH #48:c=999,e=189,p=0,cr=0,cu=0,mis=0,r=100,dep=1,og=1,tim=1262171552384262
FETCH #48:c=0,e=184,p=0,cr=0,cu=0,mis=0,r=100,dep=1,og=1,tim=1262171552384574

 

从上面所执行的SQL中可以看出的确访问了S258_IDX$表,更重要的是和SDELOB存储方式不同的是dep=1,这说明这条SQL并不是由前端应用所提交给数据库,而是数据库自己所执行的,换句话说是因为执行,前一个SQL:

SELECT 1 SHAPE, CITIES_2.OBJECTID,  CITIES_2.SHAPE.points,CITIES_2.SHAPE.numpts,CITIES_2.SHAPE.entity,CITIES_2.SHAPE.minx,CITIES_2.SHAPE.miny,CITIES_2.
SHAPE.maxx,CITIES_2.SHAPE.maxy,CITIES_2.rowid    FROM SDE.CITIES_2 CITIES_2 WHERE SDE.ST_EnvIntersects(CITIES_2.SHAPE,:1,:2,:3,:4) = 1

而导致Oracle所执行的SQL,所以ST_GEOMETRY的空间索引实现是在数据库层次上实现的。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值