现在的位置: 首页 > 综合 > 正文

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

2013年07月19日 ⁄ 综合 ⁄ 共 6104字 ⁄ 字号 评论关闭
2.2.1各种矢量数据存储类型的空间索引的实现方式

ArcSDE从开始到现在主要支持以下几种存储类型:

存储类型

数据库

SDELOB

Oracle,SQLServer,DB2

ST_GEOMETRY

Oracle,DB2,PostgresQL,Informix

SDO_GEOMETRY

Oracle

 

2.2.1.1 SDELOB

SDELOB是ArcSDE最先支持的也是最老的一种存储方式,这种存储方式类似于SHP文件的存储方式,它将属性数据和空间数据分别存储在两张表中,用ArcGIS的专业术语这两张表分别称作Business表和F表,其中Business表中存储属性数据,其简称B表,F表存储的是空间数据,至于数据库设计人员为什么将空间数据存储在以F打头的表中就不得而知了,如果是我设计,我可能把表名设计成以DATA打头。下图为抓取的B表和F表的表结构:

B表:

   1:  

SQL

> desc

 cities_1
   2:  

 Name                                      Null

?    Type
   3:  

 ----------------------------------------- -------- ----------------------------

   4:  

 OBJECTID                                  NOT

 NULL

 NUMBER(38)
   5:  

 CITY_NAME                                          NVARCHAR2(30)
   6:  

 GMI_ADMIN                                          NVARCHAR2(7)
   7:  

 ADMIN_NAME                                         NVARCHAR2(42)
   8:  

 FIPS_CNTRY                                         NVARCHAR2(2)
   9:  

 CNTRY_NAME                                         NVARCHAR2(30)
  10:  

 STATUS                                             NVARCHAR2(50)
  11:  

 POP_RANK                                           NUMBER(5)
  12:  

 POP_CLASS                                          NVARCHAR2(22)
  13:  

 PORT_ID                                            NUMBER(5)
  14:  

 LABEL_FLAG                                         NUMBER(5)
  15:  

 SHAPE                                              NUMBER(38)

F表:

   1:  

SQL

> desc

 f1464
   2:  

 Name                                      Null

?    Type
   3:  

 ----------------------------------------- -------- ----------------------------

   4:  

 FID                                       NOT

 NULL

 NUMBER(38)
   5:  

 NUMOFPTS                                  NOT

 NULL

 NUMBER(38)
   6:  

 ENTITY                                    NOT

 NULL

 NUMBER(38)
   7:  

 EMINX                                     NOT

 NULL

 FLOAT

(64)
   8:  

 EMINY                                     NOT

 NULL

 FLOAT

(64)
   9:  

 EMAXX                                     NOT

 NULL

 FLOAT

(64)
  10:  

 EMAXY                                     NOT

 NULL

 FLOAT

(64)
  11:  

 EMINZ                                              FLOAT

(64)
  12:  

 EMAXZ                                              FLOAT

(64)
  13:  

 MIN_MEASURE                                        FLOAT

(64)
  14:  

 MAX_MEASURE                                        FLOAT

(64)
  15:  

 AREA                                      NOT

 NULL

 FLOAT

(64)
  16:  

 LEN                                       NOT

 NULL

 FLOAT

(64)
  17:  

 POINTS                                             BLOB

 

两个表是通过B表的SHAPE的字段和F表的FID字段关联起来,在此也引出一个常见的问题,有很多的人发出以下的疑问:

B表的SHAPE字段的类型是NUMBER,这个数据怎么来存储空间数据呢?

从上面的介绍中可以看出来,B表的SHAPE字段并没有存储空间数据,而只是指向空间数据表的一个索引,实际的数据是存储在F表的POINTS字段中,该字段的类型是BLOB。

对于SDELOB这种存储方式也是有空间索引,只是这个空间索引并不是在数据库层次上实现的,而是在应用层次上实现的。之所以这么说,是因为,在对使用SDELOB方式存储的两张表上查不到任何的空间索引,如下图:

B表上的索引:

   1:  

SQL

> select

 index_name,index_type from

 user_indexes where

 table_name='CITIES_1'

;
   2:  

 
   3:  

INDEX_NAME                     INDEX_TYPE
   4:  

------------------------------ ---------------------------

   5:  

A1464_IX1                      NORMAL
   6:  

R2067_SDE_ROWID_UK             NORMAL

两个索引都是Btree索引

F表的索引:

   1:  

SQL

> select

 index_name,index_type from

 user_indexes where

 table_name='F1464'

;
   2:  

 
   3:  

INDEX_NAME                     INDEX_TYPE
   4:  

------------------------------ ---------------------------

   5:  

SYS_IL0000092600C00014$$       LOB
   6:  

F1464_UK1                      NORMAL

F表存在一个LOB索引和一个B-TREE索引, LOB索引从名称上能看出来是Oracle内部对BLOB字段所创建的自己维护的索引,并不是用户自己创建的,不是空间索引。

从上面的图例中可以看出来,在数据库的层面上并没有空间索引。

可能很多人并不理解在应用层面上实现的空间索引,下面来详细的解析这个问题,

先说一下索引信息的存储信息:

相信很多人都听说在ArcSDE中存在着S表,S实际上是Sptail Index Table单词的第一个字母,实际上这张表中存储的就是索引信息,以下为该表的数据结构:

   1:  

SQL

> desc

 s244_idx$
   2:  

 Name                                      Null

?    Type
   3:  

 ----------------------------------------- -------- ----------------------------

   4:  

 GX                                        NOT

 NULL

 NUMBER(38)
   5:  

 GY                                        NOT

 NULL

 NUMBER(38)
   6:  

 MINX                                     NOT

 NULL

 NUMBER(38)
   7:  

 MINY                                     NOT

 NULL

 NUMBER(38)
   8:  

 MAXX                                     NOT

 NULL

 NUMBER(38)
   9:  

 MAXY                                     NOT

 NULL

 NUMBER(38)
  10:  

 SP_ID                                     NOT

 NULL

 ROWID

红色部分就是ROWID,我在索引的基本原理提到过每个索引都会记录表记录的ROWID,在此得到了验证。

另外这张表也并不是Oracle的heap表,而是一个索引表,也就是这张表本身就是按照索引的顺序存储的,该表的具体定义可以见下图:

   1:  

SQL

> select

 dbms_metadata.get_ddl('TABLE'

,'S244_IDX$'

,'SDE'

) from

 dual;
   2:  

 
   3:  

DBMS_METADATA.GET_DDL('TABLE'

,'S244_IDX$'

,'SDE'

)
   4:  

--------------------------------------------------------------------------------

   5:  

 
   6:  

  CREATE

 TABLE

 "SDE"."S244_IDX$"
   7:  

   (    "GX" NUMBER(*,0),
   8:  

        "GY" NUMBER(*,0),
   9:  

        "MINX" NUMBER(*,0),
  10:  

        "MINY" NUMBER(*,0),
  11:  

        "MAXX" NUMBER(*,0),
  12:  

        "MAXY" NUMBER(*,0),
  13:  

        "SP_ID" ROWID,
  14:  

         CONSTRAINT

 "S244$_IX1" PRIMARY

 KEY

 ("GX", "GY", "MAXX", "MAXY", "MINX", "MINY"
  15:  

E
  16:  

 
  17:  

DBMS_METADATA.GET_DDL('TABLE'

,'S244_IDX$'

,'SDE'

)
  18:  

--------------------------------------------------------------------------------

  19:  

   ) ORGANIZATION INDEX

 NOCOMPRESS PCTFREE 0 INITRANS 4 MAXTRANS 255 LOGGING
  20:  

  STORAGE(INITIAL 65536 NEXT

 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  21:  

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT

)
  22:  

  TABLESPACE "SDE"
  23:  

 PCTTHRESHOLD 5
  24:  

  MONITORING

再解析一下应用层次上实现的意思:

在使用ArcGIS的前端软件,如Desktop, ArcGIS Server的时候,进行地图浏览的时候,尤其是在大比例尺下浏览的时候, 前端软件所提交的SQL语句是S表和F表联合查询的语句,相当于先从S表中过滤出满足条件的ROWID,然后再根据ROWID到F表中快速查到相关的记录,因此这种空间索引的实现方式是在ArcGIS的前端应用软件中实现的。

以下所摘取的是使用ArcMap浏览数据的时候所抓取的Oracle后台所执行的SQL语句。

   1:  

/opt/oracle/admin/test/udump/test_ora_15720.trc
   2:  

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
   3:  

With the Partitioning, OLAP, Data Mining and Real Application Testing options
   4:  

ORACLE_HOME = /opt/oracle
   5:  

System name:    Linux
   6:  

Node name:    lstest
   7:  

Release:    2.6.18-194.el5
   8:  

Version:    #1 SMP Tue Mar 16 21:52:39 EDT 2010
   9:  

Machine:    x86_64
  10:  

Instance name: test
  11:  

Redo thread mounted by this

 instance: 1
  12:  

Oracle process number: 15
  13:  

Unix process pid: 15720, image: oracle@lstest
  14:  

 
  15:  

*** 2010-12-14 10:25:56.311
  16:  

*** ACTION NAME:() 2010-12-14 10:25:56.310
  17:  

*** MODULE NAME:(ArcCatalog.exe) 2010-12-14 10:25:56.310
  18:  

*** SERVICE NAME:(SYS$USERS) 2010-12-14 10:25:56.310
  19:  

*** SESSION ID:(136.314) 2010-12-14 10:25:56.310
  20:  

BINDS #25:
  21:  

=====================
  22:  

PARSING IN CURSOR #25 len=69 dep=0 uid=68 oct=3 lid=68 tim=1262005426085287 hv=2558560494 ad='8ca78d78'

  23:  

SELECT table_name, time_last_modified FROM   SDE.sde_tables_modified

 
  24:  

END OF STMT
  25:  

EXEC #25:c=0,e=546,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1262005426085278
  26:  

WAIT #25: nam='SQL*Net message to client'

 ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=92612 tim=1262005426085433
  27:  

FETCH #25:c=0,e=117,p=0,cr=1,cu=0,mis=0,r=7,dep=0,og=1,tim=1262005426085510
  28:  

=====================
  29:  

PARSING IN CURSOR #45 len=443 dep=0 uid=68

 oct=3 lid=68 tim=1262005426089015 hv=2026582214 ad='83d2c968'

  30:  

SELECT /*+ INDEX(SHAPE F1464_UK1) */

 S_.eminx,S_.eminy,S_.emaxx,S_.emaxy ,SHAPE.fid,SHAPE.numofpts,SHAPE.entity,SHAPE.points,SHAPE.rowid  FROM (SELECT  /*+ INDEX(SP_ S1464_IX1) */

 DISTINCT

  31:  

 sp_fid, eminx, eminy, emaxx, emaxy FROM SDE.S1464 SP_  WHERE SP_.gx >= :1 AND SP_.gx <= :2 AND SP_.gy >= :3 AND

  32:  

 SP_.gy <= :4 AND SP_.eminx <= :5 AND SP_.eminy <= :6 AND SP_.emaxx >= :7 AND SP_.emaxy >= :8) S_, SDE.F1464 

  33:  

SHAPE  WHERE S_.sp_fid = SHAPE.fid

  34:  

END OF STMT
  35:  

EXEC #45:c=1000,e=822,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1262005426089006
  36:  

WAIT #45: nam='SQL*Net message to client'

 ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=92612 tim=1262005426095016
  37:  

WAIT #45: nam='SQL*Net more data to client'

 ela= 39 driver id=1413697536 #bytes=2004 p3=0 obj#=92612 tim=1262005426095401
  38:  

WAIT #45: nam='SQL*Net more data to client'

 ela= 23 driver id=1413697536 #bytes=2000 p3=0 obj#=92612 tim=1262005426096039
  39:  

FETCH #45:c=10998,e=10823,p=0,cr=50,cu=0,mis=0,r=57,dep=0,og=1,tim=1262005426099931

红色部分为前端软件所提交的SQL,第二个SQL即为S和F表联合查询的语句。同时请注意绿色部分的内容,dep=0 代表该SQL是应用软件所提交的SQL,并不是oracle自己内部所执行的SQL,uid=68代表执行该SQL语句的用户ID为SDE,见下面的数据:

   1:  

SQL

> select

 user_id from

 dba_users where

 username='SDE'

;
   2:  

 
   3:  

   USER_ID
   4:  

----------

   5:  

        68

至于如何抓取Oracle后台的日志,以及日志中的各项内容都代表什么意思,可以查看以下的链接:

http://blog.csdn.net/liufeng1980423/archive/2010/12/13/6072515.aspx

http://blog.csdn.net/liufeng1980423/archive/2010/12/14/6074521.aspx

【上篇】
【下篇】

抱歉!评论已关闭.