注意:这里的O,代表的是data_object_id,是与段物理存储位置相关的一个信息,因为一个段对象只可能在一个表空间上,data_object_id能唯一确认ts#,而data_object_id + rfile#就能最终定位到该rowid在那个确定的物理数据文件。
如果我们查询一个表的ROWID,就可以获得object的信息,文件信息,块信息与行信息等等,如根据其中块的信息,可以知道该表确切占用了多少个块,每行在哪个块上,哪个数据文件上。
我们在select数据时候,在不指定排序字段时, oracle是按rowid升序取数据的。如
SQL> select t.id,rowid from skate.tab2 t;
ID ROWID
---------- ------------------
1067511 AAAO1lAAEAAAHKkAAA
1067513 AAAO1lAAEAAAHKkAAB
1067515 AAAO1lAAEAAAHKkAAC
1067517 AAAO1lAAEAAAHKkAAD
1067519 AAAO1lAAEAAAHKkAAE
1067523 AAAO1lAAEAAAHKkAAG
1067525 AAAO1lAAEAAAHKkAAH
1067527 AAAO1lAAEAAAHKkAAI
8 rows selected
SQL>
可以从上面的显示数据看到,是按rowid降序排列。我们拿rowid “AAAO1lAAEAAAHKkAAA”来说明
Data Object number =AAAO1l
File id =AAE
Block id =AAAHKk
Row =AAA
Rowid是64进制的,可以通过进制转化工具来查看(http://www.2u3.cn/Conversion/jinzhi/)
A-Z <==> 0 - 25 (26)
a-z <==> 26 - 51 (26)
0-9 <==> 52 - 61 (10)
+/ <==> 62 - 63 (2)
拿其中的Data Object number= AAAO1l为例子,
l是64进制中的37,位置为0
37 * (64 ^ 0) = 37
1是64进制中的53,位置为1
53 * (64 ^ 1) = 3392
O是64进制中的 14,位置为2
14*(64^2)=57344
A是64进制中的 0
所以
A * (64 ^ 3) = 0
A * (64 ^ 4) = 0
A * (64 ^ 5) = 0
则有AAAO1l= 0 + 0 + 0 + 57344+ 3392 + 37 = 60773,表示该行存在的对象,对应的对象号为60773。
手工算还是比较麻烦的,oracle为此提供相应的函数dbms_rowid来实现
SQL> select dbms_rowid.rowid_object('AAAO1lAAEAAAHKkAAA') data_object_id#,
2 dbms_rowid.rowid_relative_fno('AAAO1lAAEAAAHKkAAA') rfile#,
3 dbms_rowid.rowid_block_number('AAAO1lAAEAAAHKkAAA') block#,
4 dbms_rowid.rowid_row_number('AAAO1lAAEAAAHKkAAA') row# from dual;
DATA_OBJECT_ID# RFILE# BLOCK# ROW#
--------------- ---------- ---------- ----------
60773 4 29348 0
可以通过包的说明或者oracle官方手册了解更多,例如:
SQL> desc dbms_rowid
Element Type
---------------------- ---------
ROWID_TYPE_RESTRICTED CONSTANT
ROWID_TYPE_EXTENDED CONSTANT
ROWID_IS_VALID CONSTANT
ROWID_IS_INVALID CONSTANT
ROWID_OBJECT_UNDEFINED CONSTANT
ROWID_CONVERT_INTERNAL CONSTANT
ROWID_CONVERT_EXTERNAL CONSTANT
ROWID_INVALID EXCEPTION
ROWID_BAD_BLOCK EXCEPTION
ROWID_CREATE FUNCTION
ROWID_INFO PROCEDURE
ROWID_TYPE FUNCTION
ROWID_OBJECT FUNCTION
ROWID_RELATIVE_FNO FUNCTION
ROWID_BLOCK_NUMBER FUNCTION
ROWID_ROW_NUMBER FUNCTION
ROWID_TO_ABSOLUTE_FNO FUNCTION
ROWID_TO_EXTENDED FUNCTION
ROWID_TO_RESTRICTED FUNCTION
ROWID_VERIFY FUNCTION
SQL> desc dbms_rowid.rowid_info
Parameter Type Mode Default
------------- -------- ---- --------
ROWID_IN ROWID IN
ROWID_TYPE NUMBER OUT
OBJECT_NUMBER NUMBER OUT
RELATIVE_FNO NUMBER OUT
BLOCK_NUMBER NUMBER OUT
ROW_NUMBER NUMBER OUT
TS_TYPE_IN VARCHAR2 IN Y
如果明白了以上ROWID的含义,那么就很容易理解块的地址rdba了,也就是ROWID中的FFFBBBBBB部分,10bit rfile#+22bit,如我们分析一个块地址:
rdba: 0x010072a4
把0x010072a4转化为10进制16806564
SQL> select dbms_utility.data_block_address_file(16806564) "file",
2 dbms_utility.data_block_address_block(16806564) "block"
3 from dual;
file block
---------- ----------
4 29348
SQL>
现在通过块的dba知道了file和block,那怎样确认我们推到的正确呢? 这个块地址是dump文件的内容,我们可以去dump文件核对下
Start dump data blocks tsn: 4