技术开发 频道

Oracle数据库的段类型详解

  下面我们将对每一种段类型进行一个简单的说明:

  TABLE:这是最常见的段类型,普通表(即非CLUSTER),没有分区,则每个表有一个类型为TABLE的段。

  INDEX:这是除了TABLE之外最常见的段类型,表的普通索引,没有分区,则每个索引有一个类型为INDEX的段。除了表上的普通索引之外,INDEX CLUSTER上的索引也是INDEX段,并且在INDEX CLUSTER上必须有一个索引(HASH CLUSTER不要求建索引)。注意IOT表的段类型为INDEX段,而不是TABLE段:

  SQL> create table t2 ( object_id number primary key,object_name varchar2(100))

  2 organization index;

  SQL> select owner,segment_type,segment_name,header_file,header_block from dba_segments where segment_name=’T2′;

  未选定行

  SQL> select index_name from user_indexes where table_name=’T2′;

  INDEX_NAME

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

  SYS_IOT_TOP_29668

  SQL> select owner,segment_type,segment_name from dba_segments where segment_name=’SYS_IOT_TOP_29668′;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  SYS INDEX SYS_IOT_TOP_29668

  注意IOT表的溢出段是TABLE类型的段:

  SQL> create table iot

  2 ( x int,

  3 y date,

  4 z varchar2(2000),

  5 constraint iot_pk primary key (x)

  6 )

  7 organization index

  8 pctthreshold 10

  9 overflow;

  表已创建。

  SQL> select owner,segment_type,segment_name from dba_segments where owner=’TEST’;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  TEST TABLE SYS_IOT_OVER_29670

  TEST INDEX IOT_PK

  TABLE PARTITION和TABLE SUBPARTITION:表分区,每个分区或子分区都有一个段。

  INDEX PARTITION和INDEX SUBPARTITION:索引分区,每个分区或子分区都有一个段。

  CLUSTER:每个CLUSTER有一个CLUSTER段。一个CLUSTER中可以存储一个或多个表。由于CLUSTER不能分区,所以没有CLUSTER PARTITION这样的段。

  LOBINDEX:表的每个LOB字段,有一个LOBINDEX段。注意对于分区表的LOB字段,每个分区上的LOB字段均会有LOBINDEX段,但是段类型为INDEX PARTITION或INDEX SUBPARTITION,这是一个特殊情况(不知道ORACLE为什么这样,从视图定义上看sys.indpart$和sys.indsubpart$没有type#字段)。

  LOBSEGMENT、LOB PARTITION、LOB SUBPARTITION:表中的每个LOB字段,有LOBSEGMENT字段,如果表进行了分区,则在每个分区上相应有LOB PARTITION和LOB SUBPARTITION:

  SQL> create table t

  2 ( id int primary key,

  3 txt clob

  4 )

  5 /

  SQL> select owner,segment_type,segment_name from dba_segments where owner=’TEST’;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  TEST TABLE T

  TEST LOBINDEX SYS_IL0000029682C00002$$

  TEST INDEX SYS_C002632

  TEST LOBSEGMENT SYS_LOB0000029682C00002$$

  注意:虽然BFILE可以作为LOB类型进行处理,但存储没有LOBINDEX和LOBSEGMENT字段:

  SQL> create table t

  2 ( id int primary key,

  3 thefile bfile

  4 )

  5 /

  SQL> select owner,segment_type,segment_name from dba_segments where owner=’TEST’;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  TEST TABLE T

  TEST INDEX SYS_C002633

  可以看到没有任何与BFILE相关的单独的段。

  ROLLBACK:就是8i及以前的回滚段,在9i以及以后的版本中,即使使用了自动撤销段管理,仍然会有一个SYSTEM回滚段。

  TYPE2 UNDO:这就是9i及以后的“撤销段”,跟ROLLBACK段类似。我们仍然习惯于叫回滚段。

  DEFERRED ROLLBACK:延迟回滚段。如果一个表空间OFFLINE时,表空间上的对象存在活动事务,则会在SYSTEM表空间中创建延迟回滚段,以便在表空间ONLINE能够回滚:

  SQL> insert into t select * from dba_objects where rownum<=10;

  已创建10行。

  SQL> alter tablespace tools offline;

  表空间已更改。

  SQL> select owner,segment_type,segment_name from dba_segments where segment_type like ‘%DEF%’;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  SYS DEFERRED ROLLBACK 1.84337

  TEMPORARY:临时段。除了磁盘排序产生临时段之外,临时表也会有临时段。另外,在CTAS过程中,如果SQL还没有最终完成,这个时候的表对应的段为TEMPORARY表,只有在SQL执行的最后将TEMPORARY段改为TABLE段。比如:

  SQL> create table t2 as select * from dba_objects;

  在执行上面语句的同时,执行:

  SQL> select segment_type,owner,segment_name from dba_segments where segment_type=’TEMPORARY’;

  SEGMENT_TYPE OWNER SEGMENT_NAME

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

  TEMPORARY SYS 1.84337

  可以看到临时段,在CTAS执行完之后,我们可以看到:

  SQL> select segment_type,owner,segment_name from dba_segments where segment_type=’TEMPORARY’;

  未选定行

  SQL> select header_file,header_block from dba_segments where owner=USER and segment_name=’T2′;

  HEADER_FILE HEADER_BLOCK

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

  1 84337

  可以看到,之前的临时段(其段名为一个特别的名字1.84337,段头的文件号和块号),与CTAS后的表的段头一致。

  另外在表和索引的MOVE、REBUILD阶段也会有临时段。所以临时段不一定是在临时表中,在普通的表空间中也可能会存在。

  注意在排序段和临时表的段在并没有在DBA_SEGMENTS视图,而是在V$TEMPSEG_USAGE视图中。

  CACHE:这是一个特殊的段,为Oracle的自举(bootstrap)段。

  SQL> select owner,segment_type,segment_name,header_file,header_block from dba_segments where segment_type=’CACHE’;

  OWNER SEGMENT_TYPE SEGMENT_NAME HEADER_FILE HEADER_BLOCK

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

  SYS CACHE 1.833 1 833

  我们通过DUMP数据文件头可以发现:

  FILE HEADER:

  Software vsn=153092096=0×9200000, Compatibility Vsn=134217728=0×8000000

  Db ID=2968647772=0xb0f1f85c, Db Name=’XJ’

  Activation ID=0=0×0

  Control Seq=761=0×2f9, File size=128000=0×1f400

  File Number=1, Blksiz=4096, File Type=3 DATA

  Tablespace #0 - SYSTEM rel_fn:1

  Creation at scn: 0×0000.00000009 05/12/2002 16:20:42

  Backup taken at scn: 0×0000.00000000 01/01/1988 00:00:00 thread:0

  reset logs count:0×26ce9ece scn: 0×0000.000a65e0 recovered at 07/19/2008 21:23:10

  status:0×4 root dba:0×00400341 chkpt cnt: 272 ctl cnt:271

  root dba转换为文件号和块号则为1.833,正好是类型为CACHE的段头。Oracle通过文件号为1的文件头的root dba定位到自举对象,然后得到obj$等核心对象所在位置,来进行启动。

  NESTED TABLE:嵌套表的段,以面举例子说明:

  SQL> create or replace type emp_type

  2 as object

  3 (empno number(4),

  4 ename varchar2(10),

  5 job varchar2(9),

  6 mgr number(4)

  7 );

  8 /

  类型已创建。

  SQL> create or replace type emp_tab_type

  2 as table of emp_type;

  3 /

  类型已创建。

  SQL> create table dept_and_em

  2 (deptno number(2) primary key,

  3 dname varchar2(14),

  4 loc varchar2(13),

  5 emps emp_tab_type,

  6 emps2 emp_tab_type

  7 )

  8 nested table emps store as emps_nt

  9 nested table emps2 store as emps_nt2;

  表已创建。

  SQL> select owner,segment_type,segment_name from dba_segments where owner=’TEST’;

  OWNER SEGMENT_TYPE SEGMENT_NAME

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

  TEST NESTED TABLE EMPS_NT

  TEST NESTED TABLE EMPS_NT2

  TEST TABLE DEPT_AND_EM

  TEST INDEX SYS_C002629

  TEST INDEX SYS_C002630

  TEST INDEX SYS_C002631

  这里看到有两个类型为NESTED TABLE的段。另外除了主键之外,每个NESTED TABLE字段上还有一个索引(实际上是每个NESTED TABLE字段对应一具隐含字段,上面建有索引)。

1
相关文章