oracle object_id和data_object_id的區別


Oracle的數據字典表dba_objects包含了兩個字段,object_id, data_object_id,官方文檔上的解釋是:

object_id: Dictionary object number of the object.
Data_object_id: Dictionary object number of the segment that contains the object.

直譯一下是:

object_id:對象的數據字典標示。
Data_object_id:包含對象的段的數據字典標示。

直譯下來還是很難理解,不過下面就詳細講解他們的區別:

  首先,區別一下段(segment)和數據字典對象(dictionary object)的概念,段(segment)是指實實在在的分配了一個或者多個區(extents)來存儲數據。而數據字典對象(dictionary object)有可能有存儲區域,也有可能沒有。比如sequence,package,type這些對象並沒有存儲空間,所以並不存在段與之相關聯。所以這些對象的data_object_id都是空值。

  

XPCHILD/XPCHILD@ORCL>select object_id, data_object_id from dba_objects where object_name='SEQ_TEST'; 
OBJECT_ID     DATA_OBJECT_ID
---------- --------------
36385

下面看一個實際的例子,就能夠很好的理解這兩個概念了:

1.  move 操作:

XPCHILD/XPCHILD@ORCL>select object_id, data_object_id from dba_objects where object_name='TEST1';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     36386          36386

1 row selected.
XPCHILD/XPCHILD@ORCL>alter table test1 move;

Table altered.
XPCHILD/XPCHILD@ORCL>select object_id, data_object_id from dba_objects where object_name='TEST1';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     36386          36387

可以看到,test1在創建的時候,object_id, data_object_id都是36386.這是因為在創建的時候數據字典分配的機制是相同的。使用move操作,而本身move操作只是重新分配了空間來重組原來的數據,所以對象本身沒有發生變化,而是重新分配了段來存儲數據。

2.  partition分區表

  

XPCHILD/XPCHILD@ORCL>CREATE TABLE test2
  2  (id number,  status char(1)) 
PARTITION BY list(status)  (PARTITION p_t VALUES ('t'), PARTITION p_f VALUES ('f'));

Table created.

XPCHILD/XPCHILD@ORCL>select object_name, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID from dba_objects where object_name='TEST2';

OBJECT_NAM SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID
---------- ------------------------------ ---------- --------------
TEST2      P_F                                 36390          36390
TEST2      P_T                                 36389          36389
TEST2                                          36388

3 rows selected

這個地方可以看出,test2對象只有object_id,而真正只有分區才會有data_object_id, 因為每一個分區分配了一個段。

接着再創建一個普通表:

  

XPCHILD/XPCHILD@ORCL>CREATE TABLE test3
   ( id number,
    status char(1)
   );

XPCHILD/XPCHILD@ORCL>select object_name, object_id, data_object_id from dba_objects where object_name='TEST3';

OBJECT_NAM  OBJECT_ID DATA_OBJECT_ID
---------- ---------- --------------
TEST3           36391          36391

然后進行分區交換:

XPCHILD/XPCHILD@ORCL>alter table test2 exchange partition p_t with table test3 including indexes;

Table altered.

最后再看一下相關的object_id和data_object_id:

XPCHILD/XPCHILD@ORCL>select object_name, SUBOBJECT_NAME, object_id, data_object_id from dba_objects where object_name in ('TEST2','TEST3');

OBJECT_NAM SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID
---------- ------------------------------ ---------- --------------
TEST2      P_F                                 36390          36390
TEST2      P_T                                 36389          36391
TEST2                                          36388
TEST3                                          36391          36389

所以這個地方顯而易見,在交換過后,對象的object_id都不會發生變變化,因為exchange操作並不會遷移數據,而僅僅是更改了對象的數據存儲即段得指向,也就是更改了對象的指針,這個指針指向的是數據存儲區域,即所謂的段。

3.   最后再看一下rowid

  

rowid是指數據塊中行的物理地址。看一下rowid的組成:
XPCHILD/XPCHILD@ORCL>select rowid ,
  2  substr(rowid,1,6) "OBJECT",
  3  substr(rowid,7,3) "FILE",
  4  substr(rowid,10,6) "BLOCK",
  5  substr(rowid,16,3) "ROW",
  6  dbms_rowid.rowid_object(rowid) object_id,
  7  id
  8  from test3 t;

ROWID              OBJECT       FILE   BLOCK        ROW     OBJECT_ID         ID
------------------ ------------ ------ ------------ ------ ---------- ----------
AAAI4lAAMAAAhssAAA AAAI4l       AAM    AAAhss       AAA         36389          1

1 row selected.

XPCHILD/XPCHILD@ORCL>alter table test3 move;

Table altered.


XPCHILD/XPCHILD@ORCL>select rowid ,
  2  substr(rowid,1,6) "OBJECT",
  3  substr(rowid,7,3) "FILE",
  4  substr(rowid,10,6) "BLOCK",
  5  substr(rowid,16,3) "ROW",
  6  dbms_rowid.rowid_object(rowid) object_id,
  7  id
  8  from test3 t;

ROWID              OBJECT       FILE   BLOCK        ROW     OBJECT_ID         ID
------------------ ------------ ------ ------------ ------ ---------- ----------
AAAI4oAAMAAAhtMAAA AAAI4o       AAM    AAAhtM       AAA         36392          1

1 row selected.

  可以看到,rowid表示的是數據的在塊中的地址,所以在rowid的組成中,object_id是所謂的段的數據字典id,即data_object_id,如上所示,對表進行move操作,object_id發生了變化,即驗證了這個猜想。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM