oracle中的Rowid和Urowid

tengrid發表於2009-05-18

Oracle使用rowid資料型別儲存行地址,rowid可以分成兩種,分別適於不同的對像

Physical rowids:儲存ordinary table,clustered table,table partition and subpartition,indexe,index partition and subpartition

Logical rowids : 儲存IOT的行地址

 

另一種rowid型別叫universal rowed(UROWID),支援上述physical rowidlogical rowed,並且支援非oracle table, 即支援所有型別的rowid, COMPATIBLE必須在8.1或以上.

 

1.1 ROWID偽列

     每個表在oracle內部都有一個ROWID偽列,它在所有sql中無法顯示,不佔儲存空間; 它用於從表中查詢行的地址或者在where中進行參照,一個例子如下:

     SELECT ROWID, last_name FROM employees;

     Oracle內部使用保留在ROWID偽列中的值構建索引結構

     再次強調一次,rowid偽列不儲存在資料庫中,它不是資料庫資料,這是從databasetable的邏輯結構來說的,事實上,在物理結構上,每行由一個或多個row pieces組成,每個row piece的頭部包含了這個pieceaddress,rowid.從這個意義上來說,rowid還是佔了磁碟空間的.

    我們在建立表時,可以為列指定為rowid資料型別,但oracle並不保證列中的資料是合法的rowid,必須由應用程式來保證, 另外,型別為rowid的列需要6 bytes儲存資料

 

1.2, physical rowids

    

只在行存在,它的實體地址rowid就不會變化,除非export/import,根據rowid可以直接定位到blockfetch資料,所以physical兼具有高穩定(stability)和高效能(performance)的特點.

這裡要注意一點,對於clustered table來說,根據它的儲存特點,在同一個block中的不同table的行可能具有同一個rowid; nonclustered table,每一行或初始行片(initial row piece)都有唯一的rowid

要注意rowid的地址固定的特點,在一個block的某一行被deletecommit後,它佔據的address可以被其它事務新insert的行重用.

 

Physical rowid可以是下面任一一種格式:

     1) Extended rowid

         使用表空間相關的資料塊地址,8i及以上使用這種格式

        

2) Restricted rowid

    使用資料庫範圍的資料址地址,oracle 7或更早前的版本使用

1.2.1 extened rowid

       擴充套件行地址是64編碼的實體地址,編碼字元是A-Z, a-z, 0-9, +, and /.

       4部分組成 OOOOOOFFFBBBBBBRRR (obj#file#block#row#)

       

       OOOOOO -–data object number

        FFF –-表空間相對的資料檔案號

        BBBBBB –-塊號

        RRR ---行號

        注意不是16進製表示

       SQL> select rowid,name from obj$ where rownum<=10;

 

ROWID              NAME

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

AAAAASAABAAAAB6ABc ACCESS$

AAAAASAABAAAC1QAAK AGGXMLIMP

AAAAASAABAAAC1QAAL AGGXQIMP

AAAAASAABAAAGiRAAI ALERT_QT

AAAAASAABAAAGiRAAh ALERT_QUE

AAAAASAABAAAGujAAo ALERT_QUE$1

AAAAASAABAAAGujAAp ALERT_QUE$1

AAAAASAABAAAGiRAAf ALERT_QUE_N

AAAAASAABAAAGiRAAe ALERT_QUE_R

AAAAASAABAAAGiRAAG ALERT_TYPE

 

我們可以使用dbms_rowidextened rowid中抽取各部分資訊 ,或者將extened rowid轉換成restricted rowed,詳細的資訊參見sys.dbms_rowid的規範

 

#根據rowid抽塊對像編號

SQL> select dbms_rowid.rowid_object('AAAAASAABAAAGiRAAG') obj#  from dual;

 

      OBJ#

----------

        18

#根據rowid抽取表空間相對檔案號

SQL> select dbms_rowid.rowid_relative_fno('AAAAASAABAAAGiRAAG') rfile# from dual;

     RFILE#

----------

         1

#根據rowid抽取塊號

SQL> select dbms_rowid.ROWID_BLOCK_NUMBER('AAAAASAABAAAGiRAAG') block# from dual;

 

    BLOCK#

----------

     26769

#根據rowid抽取行號

SQL> select dbms_rowid.rowid_row_number('AAAAASAABAAAGiRAAG') row#  from dual;

 

      ROW#

----------

         6

#extended rowid轉換成為restricted rowid

SQL> select dbms_rowid.rowid_to_restricted('AAAAASAABAAAGiRAAG',0) restricted_rowid  from dual;

 

RESTRICTED_ROWID

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

00006891.0006.0001

 

1.2.2 restricted rowid

限制地址行號與擴充套件地址行號編碼方式不一樣,它在內部使用二進位制方式表示,當用select查詢時,會轉換成varchar2/16進位制的混合形式,它的組織方式如下:

BBBBBBBB.RRRR.FFFF  (block#.row#.file#)

注意,這裡的檔案號是絕對檔案號,extended rowid中是相對檔案號(相對錶空間)

 Restricted rowid中不再有object number,因為從絕對檔案號可以唯一確定資料塊

 樣例可以參考前面的00006891.0006.0001

     另外請注意, 塊中的行號是從0開始

 

除了用dbms_rowid來抽取rowid的不同部分外,也可以用substr

#extended rowid

SQL> SELECT ROWID,

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

相關文章