Oracle redo解析之-4、rowid的計算

門牙發表於2019-04-07

對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

圖片 1.png

	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來進行查詢的。

相關文章