object_id與data_object_id淺析(一)

realkid4發表於2011-03-26

我們經常使用的資料字典檢視_objects(xxx代指dba/all/user)中,有資料列object_id用於標誌資料物件。在很多時候,我們習慣於使用該標識進行物件資訊跟蹤和定位。但是,在該檢視中,還包括一個名稱data_object_id的列,它表示的是一個什麼含義呢?我們一起來分析一下。

 

實驗環境構建

 

//我們選擇10gR2版本

SQL> select * from v$version;

 

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE       10.2.0.1.0       Production

 

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

//構建實驗資料表

SQL> create table t as select * from dba_objects;

 

Table created

//資料字典資訊展示

SQL> select object_id,data_object_id from user_objects where object_name='T';

 

 OBJECT_ID DATA_OBJECT_ID

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

54038          54038

 

SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';

 

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

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

T                              4         4203

 

 

此時,我們注意一下:試驗的資料表T,其object_id為54038,data_object_id相同也為54038。物理段位置上,位於4號資料檔案,頭塊編號為4203。

 

 

資料字典分析

 

首先我們分析一下dba_objects資料字典檢視兩個對應列的來源。從檢視的解釋資訊上看,object_id和data_object_id分別為:

 

 

OBJECT_IDObject number of the object                                                 

DATA_OBJECT_ID Object number of the segment which contains the object                      

 

 

從檢視註釋資訊上看,object_id的含義是物件的唯一性編號。而data_object_id表示的是資料表對應的段位置編號。簡單的說,一個表示邏輯唯一編號,一個表示物理儲存上的唯一編號。

 

分析資料字典dba_objects來源,可以抽絲剝繭。檢查dba_objects檢視的基礎來源。這時候我們的方法很多,比如使用dbms_metadata.get_ddl方法。這次我們直接研究資料字典的生成指令碼catalog.sql檔案中的內容。

 

 

create or replace view DBA_OBJECTS

    (OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID,

     OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS,

     TEMPORARY, GENERATED, SECONDARY)

as

select u.name, o.name, o.subname, o.obj#, o.dataobj#,

       decode(o.type#, 0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER',

                     (篇幅原因,省略部分……

                     'UNDEFINED'),

       o.ctime, o.mtime,

       to_char(o.stime, 'YYYY-MM-DD:HH24:MI:SS'),

       decode(o.status, 0, 'N/A', 1, 'VALID', 'INVALID'),

       decode(bitand(o.flags, 2), 0, 'N', 2, 'Y', 'N'),

       decode(bitand(o.flags, 4), 0, 'N', 4, 'Y', 'N'),

       decode(bitand(o.flags, 16), 0, 'N', 16, 'Y', 'N')

from sys.obj$ o, sys.user$ u

(篇幅原因,省略部分

 

上述為catalog.sql指令碼中對dba_objects的定義片段,處於篇幅的考慮將於本篇無關的內容加以省略。注意:這個是Oracle10gR2的dba_objects定義,在11g中存在一些差異,留待以後的討論。

 

從上面的指令碼中,我們確定dba_objects檢視物件的主要資訊來源自底層資料字典表obj$和user$。我們之前討論過關於Oracle層次結構的資料字典,http://space.itpub.net/17203031/viewspace-686814,obj$屬於底層資料字典結構。其中,我們關注的object_id和data_object_id欄位就是對應obj$資料表的obj#和dataobj#欄位。

 

那麼,這兩個欄位在obj$中的解釋是什麼呢?因為obj$資料表對應列沒有comment資訊。我們搜尋sql.bsp檔案,發現如下的檔案片段。

 

 

create table obj$                                            /* object table */

( obj#          number not null,                            /* object number */

  /* DO NOT CREATE INDEX ON DATAOBJ#  AS IT WILL BE UPDATED IN A SPACE

   * TRANSACTION DURING TRUNCATE */

  dataobj#      number,                          /* data layer object number */

  owner#        number not null,                        /* owner user number */

(篇幅原因,省略部分

 

 

sql.bsp指令碼中,定義了資料庫基礎結構表的內容,其中一些註釋資訊,往往包含著重要資訊內容。這裡我們發現了obj#和dataobj#的一些端倪。

 

首先,obj#是一個物件標誌,在資料庫中作為一個物件的唯一標識。而dataobj#給出的內部說明是“data layer object number”,是資料層物件的編號。並且最值得注意的是上面關於dataobj#的描述:Oracle要求不要對這個資料列加索引,因為該列取值會由於進行truncate操作而發生變化。

 

 

在資料字典obj$的內容說明中,我們可以猜測dataobj#是一種描述物件物理儲存的標誌。truncate操作雖然從效果上是快速進行資料刪除,但是本質上是一種ddl語句,重構資料結構。下面我們透過實驗進行說明。

 

 

Truncate Table實驗

 

還是剛剛環境準備的實驗資料表。我們分別進行一般性delete刪除和truncate兩種刪除操作,比較變化效果。

//啟用跟蹤檔案方法

SQL> alter session set events '10046 trace name context forever, level 4';

 

Session altered

 

SQL> delete t;

 

50355 rows deleted

 

SQL> commit;

 

Commit complete

 

SQL> select f_get_trace_name from dual;

 

F_GET_TRACE_NAME

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

D:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_1236.trc

 

 

之後,我們觀察資料表T的邏輯物理結構情況。

 

 

SQL> select object_id,data_object_id from user_objects where object_name='T';

 

 OBJECT_ID DATA_OBJECT_ID

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

54038          54038

 

SQL> col segment_name for a20;

SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';

 

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

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

T                              4         4203

 

 

發現,物件編號和物理編號都沒有發生變化。對應的segment_name結構也沒有任何的變化,包括檔案位置和段頭塊編號等。同時分析跟蹤檔案orcl_ora_1236.trc,也沒有發現更新obj$資料表的連帶操作痕跡。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-690629/,如需轉載,請註明出處,否則將追究法律責任。

相關文章