程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 通過Oracle9i的數據字典來探討Oracle的段類型

通過Oracle9i的數據字典來探討Oracle的段類型

編輯:Oracle數據庫基礎
我們這裡討論一下Oracle數據庫中到底有多少類型的段,除了常見的TABLE、INDEX之外還有哪些?下面通過Oracle9i的數據字典來探討Oracle的段類型。

  SQL> select distinct segment_type from dba_segments;

  SEGMENT_TYPE

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

  CACHE

  CLUSTER

  INDEX

  INDEX PARTITION

  LOBINDEX

  LOBSEGMENT

  NESTED TABLE

  ROLLBACK

  TABLE

  TABLE PARTITION

  TYPE2 UNDO

  然而在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 /* exclude clustered tables */

  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 ‘%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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved