您的位置:首页 > 数据库 > Oracle

Oracle数据库的段类型详解

2016-01-17 16:53 489 查看
【IT168
技术文档】
Oracle数据库中有多少类型的段,除了常见的TABLE、INDEX之外还有哪些?下面通过Oracle9i的数据字典来探讨Oracle的段类型。

SQL> select distinct
segment_type from dba_segments;

SEGMENT_TYPE

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

LOBINDEX

INDEX PARTITION

TABLE PARTITION

NESTED TABLE

ROLLBACK

LOB PARTITION

LOBSEGMENT

INDEX

TABLE

CLUSTER

TYPE2 UNDO

已选择11行。

  然而在DBA_SEGMENTS视图中,不一定包含了所有的段类型,我们从DBA_SEGMENTS的定义中去寻找Oracle的段类型。

  SQL> select text from dba_views where
view_name='DBA_SEGMENTS';

  TEXT

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

  select owner, segment_name, partition_name, segment_type,
tablespace_name,

  header_file, header_block,

  dbms_space_admin.segment_number_blocks(tablespace_id,
relative_fno,

  header_block, segment_type_id, buffer_pool_id, segment_flags,

  segment_objd, blocks)*blocksize,

  dbms_space_admin.segment_number_blocks(tablespace_id,
relative_fno,

  header_block, segment_type_id, buffer_pool_id, segment_flags,

  segment_objd, blocks),

  dbms_space_admin.segment_number_extents(tablespace_id,
relative_fno,

  header_block, segment_type_id, buffer_pool_id, segment_flags,

  segment_objd, extents),

  initial_extent, next_extent, min_extents, max_extents,
pct_increase,

  freelists, freelist_groups, relative_fno,

  decode(buffer_pool_id, 0, ‘DEFAULT’, 1, ‘KEEP’, 2, ‘RECYCLE’,
NULL)

  from sys_dba_segs

  SQL> select text from dba_views where
view_name=’SYS_DBA_SEGS’;

  TEXT

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

  select u.name, o.name, o.subname,

  so.object_type, s.type#,

  ts.ts#, ts.name, ts.blocksize,

  f.file#, s.block#,

  s.blocks * ts.blocksize, s.blocks, s.extents,

  s.iniexts * ts.blocksize,

  decode(bitand(ts.flags, 3), 1, to_number(NULL),

  s.extsize * ts.blocksize),

  s.minexts, s.maxexts,

  decode(bitand(ts.flags, 3), 1, to_number(NULL),

  s.extpct),

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.lists, 0, 1, s.lists)),

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.groups, 0, 1, s.groups)),

  s.file#, s.cachehint, NVL(s.spare1,0), o.dataobj#

  from sys.user$ u, sys.obj$ o, sys.ts$ ts, sys.sys_objects so,
sys.seg$ s,

  sys.file$ f

  where s.file# = so.header_file

  and s.block# = so.header_block

  and s.ts# = so.ts_number

  and s.ts# = ts.ts#

  and o.obj# = so.object_id

  and o.owner# = u.user#

  and s.type# = so.segment_type_id

  and o.type# = so.object_type_id

  and s.ts# = f.ts#

  and s.file# = f.relfile#

  select u.name, un.name, NULL,

  decode(s.type#, 1, ‘ROLLBACK’, 10, ‘TYPE2 UNDO’), s.type#,

  ts.ts#, ts.name, ts.blocksize, f.file#, s.block#,

  s.blocks * ts.blocksize, s.blocks, s.extents,

  s.iniexts * ts.blocksize, s.extsize * ts.blocksize,
s.minexts,

  s.maxexts, s.extpct,

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.lists, 0, 1, s.lists)),

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.groups, 0, 1, s.groups)),

  s.file#, s.cachehint, NVL(s.spare1,0), un.us#

  from sys.user$ u, sys.ts$ ts, sys.undo$ un, sys.seg$ s, sys.file$
f

  where s.file# = un.file#

  and s.block# = un.block#

  and s.ts# = un.ts#

  and s.ts# = ts.ts#

  and s.user# = u.user#

  and s.type# in (1, 10)

  and un.status$ != 1

  and un.ts# = f.ts#

  and un.file# = f.relfile#

  union all

  select u.name, to_char(f.file#) || ‘.’ || to_char(s.block#),
NULL,

  decode(s.type#, 2, ‘DEFERRED ROLLBACK’, 3, ‘TEMPORARY’,

  4, ‘CACHE’, 9, ‘SPACE HEADER’, ‘UNDEFINED’), s.type#,

  ts.ts#, ts.name, ts.blocksize,

  f.file#, s.block#,

  s.blocks * ts.blocksize, s.blocks, s.extents,

  s.iniexts * ts.blocksize,

  decode(bitand(ts.flags, 3), 1, to_number(NULL),

  s.extsize * ts.blocksize),

  s.minexts, s.maxexts,

  decode(bitand(ts.flags, 3), 1, to_number(NULL),

  s.extpct),

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.lists, 0, 1, s.lists)),

  decode(bitand(ts.flags, 32), 32, to_number(NULL),

  decode(s.groups, 0, 1, s.groups)),

  s.file#, s.cachehint, NVL(s.spare1,0), s.hwmincr

  from sys.user$ u, sys.ts$ ts, sys.seg$ s, sys.file$ f

  where s.ts# = ts.ts#

  and s.user# = u.user#

  and s.type# not in (1, 5, 6, 8, 10)

  and s.ts# = f.ts#

  and s.file# = f.relfile#

  SQL> select text from dba_views where
view_name=’SYS_OBJECTS’;

  TEXT

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

  select decode(bitand(t.property, 8192), 8192, ‘NESTED TABLE’,
‘TABLE’), 2, 5,

  t.obj#, t.file#, t.block#, t.ts#

  from sys.tab$ t

  where bitand(t.property, 1024) = 0

  union all

  select ‘TABLE PARTITION’, 19, 5,

  tp.obj#, tp.file#, tp.block#, tp.ts#

  from sys.tabpart$ tp

  union all

  select ‘CLUSTER’, 3, 5,

  c.obj#, c.file#, c.block#, c.ts#

  from sys.clu$ c

  union all

  select decode(i.type#, 8, ‘LOBINDEX’, ‘INDEX’), 1, 6,

  i.obj#, i.file#, i.block#, i.ts#

  from sys.ind$ i

  where i.type# in (1, 2, 3, 4, 6, 7, 8, 9)

  union all

  select ‘INDEX PARTITION’, 20, 6,

  ip.obj#, ip.file#, ip.block#, ip.ts#

  from sys.indpart$ ip

  union all

  select ‘LOBSEGMENT’, 21, 8,

  l.lobj#, l.file#, l.block#, l.ts#

  from sys.lob$ l

  union all

  select ‘TABLE SUBPARTITION’, 34, 5,

  tsp.obj#, tsp.file#, tsp.block#, tsp.ts#

  from sys.tabsubpart$ tsp

  union all

  select ‘INDEX SUBPARTITION’, 35, 6,

  isp.obj#, isp.file#, isp.block#, isp.ts#

  from sys.indsubpart$ isp

  union all

  select decode(lf.fragtype$, ‘P’, ‘LOB PARTITION’, ‘LOB
SUBPARTITION’),

  decode(lf.fragtype$, ‘P’, 40, 41), 8,

  lf.fragobj#, lf.file#, lf.block#, lf.ts#

  from sys.lobfrag$ lf

  因此,从以上几个视图的定义中可以看到,Oracle9i中有如下的段类型:

  NESTED TABLE

  TABLE

  TABLE PARTITION

  CLUSTER

  LOBINDEX

  INDEX

  INDEX PARTITION

  LOBSEGMENT

  TABLE SUBPARTITION

  INDEX SUBPARTITION

  LOB PARTITION

  LOB SUBPARTITION

  ROLLBACK

  TYPE2 UNDO

  DEFERRED ROLLBACK

  TEMPORARY

  CACHE

  SPACE HEADER

  UNDEFINED
内容导航

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

  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 ‘�F%’;

  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字段对应一具隐含字段,上面建有索引)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: