Welcome 微信登录

首页 / 数据库 / MySQL / Oracle的rowid和rdba庖丁解牛

Oracle 8以下ROWID组成(也叫受限Rowid)为:FFFF.BBBBBBBB.RRRR,占用6个字节(10bit file#+22bit+16bit),但是,为了扩充的需要,如数据文件的扩充,现在的Rowid改为:OOOOOOFFFBBBBBBRRR,占用10个字节(32bit+10bit rfile#+22bit+16bit)。其中,O是对象ID,F是文件ID,B是块ID,R是行ID。由于rowid的组成从file#变成了rfile#,所以数据文件数的限制也从整个库不能超过1023个变成了每个表空间不能超过1023个数据文件。注意:这里的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 AAAO1lAAEAAAHKkAAI8 rows selectedSQL> 可以从上面的显示数据看到,是按rowid降序排列。我们拿rowid “AAAO1lAAEAAAHKkAAA”来说明 Data Object number =AAAO1lFile id                  =AAE     Block id              =AAAHKkRow        =AAARowid是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,位置为037 * (64 ^ 0) = 371是64进制中的53,位置为153 * (64 ^ 1) = 3392O是64进制中的 14,位置为214*(64^2)=57344A是64进制中的 0所以A * (64 ^ 3) = 0A * (64 ^ 4) = 0A * (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_rowidElement                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_infoParameter     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进制16806564SQL>   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 file#: 4 minblk 29348 maxblk 29348buffer tsn: 4 rdba: 0x010072a4 (4/29348)scn: 0x0000.00e66a1e seq: 0x02 flg: 0x06 tail: 0x6a1e0602frmt: 0x02 chkval: 0x4590 type: 0x06=trans dataHex dump of block: st=0, typ_found=1 结果我们推导的和dump的内容是一样的,不过这里得到的4是rfile#,相对文件号,而相对文件号是不能超过1023,所以,如果你想根据这个地址来dump数据文件块的话,最好还是核对一下v$datafile:select file# from v$datafile where rfile# = 4 and ts# = <:dbfile_in_ts> 表空间的ts#可以通过如下sql得到:  select ta.tablespace_name, da.TS#
    from dba_tablespaces ta, dba_data_files df, v$datafile da
   where ta.tablespace_name = df.tablespace_name
     and da.NAME = df.file_name 例如:SQL> select file# from v$datafile where rfile# = 4 and ts# = 4;     FILE#----------         4SQL> 如果数据文件数大于1023个,这里file# 就不是4了,应该是个绝对文件号了,这就是file#和rfile#的区别。如果dump数据块,要用绝对文件号的,例如:Alter system dump  datafile 4 block 29348; 也可以通过dba_segments,如SQL>  select header_file,header_block from dba_segments where owner="SKATE" and segment_name="TAB2"; HEADER_FILE HEADER_BLOCK----------- ------------          4        29347这里段头占有一个block,后面存储的就是数据,所以存储数据的块,应该是29348 -----end-----Oracle表连接深入浅出MySQL的一些常用操作相关资讯      oracle 
  • [INS-32052] Oracle基目录和Oracle  (07/22/2014 07:41:41)
  • Oracle 4个大对象(lobs)数据类型  (02/03/2013 12:33:05)
  • Oracle按时间段分组统计  (07/26/2012 10:36:48)
  • [Oracle] dbms_metadata.get_ddl的  (07/12/2013 07:37:30)
  • Liferay Portal 配置使用Oracle和  (07/31/2012 20:07:18)
  • Concurrent Request:Inactive   (07/20/2012 07:44:05)
本文评论 查看全部评论 (0)
表情: 姓名: 字数