對rowid的理解
rowid是資料庫的一個偽列,在建立表的時候Oracle會自動為每個表建立ROWID列。偽列實際上不儲存在表中,可以從這些偽列中查詢值,但不能插入、更新或刪除。
rowid是用來唯一標識一行記錄的,是儲存每條記錄的實際實體地址。
查詢某條記錄的rowid值
SQL> select ROWID from user_test where rownum<3;
ROWID
------------------
AAAQObAAFAAAACDAAA
AAAQObAAFAAAACFAAA
rowid的格式如下:
1. 資料物件編號: AAAQOb, data_obj#,即obj$
2. 相對檔案編號: AAF, file#
3. 塊編號: AAAACD, block#
4. 行編號: AAA, slot
複製程式碼
計算具體的dataobj#, file#, block#, slot
rowid是base64編碼,用A-Z,a-z, 0-9,+,/共64個字元來表示,A表示0,B表示1等等。
則:
data_obj#=AAAQOb=0*64^5 + 0*64^4 + 0*64^3 + 16*64^2 + 14*64^1 + 27*64^0 = 66459
file#=AAF=0*64^2 + 0*64^1 + 5*64^0 = 5
block#=AAAACD=2*64^1 + 3*64^0 = 128
slot=AAA = 0
複製程式碼
根據data_obj#, file#, block#, slot計算rowid
實際上就是將十進位制數轉化成64進位制,當然從二進位制轉換比較簡單。
將二進位制數從右往左,6位一組,然後將這6位二進位制轉成十進位制,然後替換成base64的字元即可。
例:
dataobj#=66444=1 00000011 10001100 = 010000 001110 001100 = 16 14 12 = Q O M = AAAQOM(補齊6位)
file#=1 = AAB
block#=70321=1 00010010 10110001 = 010001 001010 110001 = 17 10 49 = R K x = AAARKx
slot=0 = AAA
則:rowid=AAAQOMAABAAARKxAAA
複製程式碼
SQL查詢出data_obj#,file#,block#,slot的值
SQL> select dbms_rowid.rowid_object(rowid) object_id,
2 dbms_rowid.rowid_relative_fno(rowid) file_id,
3 dbms_rowid.rowid_block_number(rowid) block_id,
4 dbms_rowid.rowid_row_number(rowid) num
5 from user_test;
OBJECT_ID FILE_ID BLOCK_ID NUM
---------- ---------- ---------- ----------
66459 5 131 0
66459 5 133 0
複製程式碼
#總結 根據data_obj#確定資料儲存的資料段,根據file#確定資料所在的檔案,根據block#確定資料儲存在檔案的哪裡塊,根據slot確定資料儲存在塊中的哪一行,因此根據rowid可以具體定位資料的位置。對資料庫中記錄行的最快檢索操作就是通過rowid來進行查詢的。