首页 > 代码库 > Oracle rowid

Oracle rowid

一.Rowid

  rowid是伪列(pseudocolumn),伪劣的意思是实际上这一列本身在数据字典中并不存在,在查询结果输出时它被构造出来的。

  rowid并不会真正存在于表的data block中,但是他会存在于index当中,用来通过rowid来寻找表中的行数据

二.Rowid的结构

  限制rowid:用于早期Oracle版本(Oracle 8 以前),rowid由(10 bit)file#+(22 bit)block#+(16 bit)row#组成,占用6个bytes的空间

  注:file#为10位,故整个数据库最多只能有的2^10-2=1022个数据文件(去掉全0和全1)

  扩展rowid:由data_object#+rfile#+block#+row#组成,占用10个bytes的空间,显示为18位的字符串

  扩展rowid包含下列组成元素:

  1. 数据对象编号(32 bit):对应dba_objects.data_object_id.此编号确定所属表空间,因为一个段对象只属于一个表空间                           
  2. 相对文件编号(10 bit):对应dba_extents.relative_fno.此编号对于表空间中的每个数据文件是唯一的,故每个表空间中可以最多有2^10-2个数据文件
  3. 块编号(22 bit):表示包含此行的块在数据文件中的位置
  4. 行编号(16 bit):标识块头中行目录位置的位置

  定位一行记录的顺序是:数据对象(表空间)-->数据文件(此表空间中的)-->块编号(此数据文件中的)-->定位行(此块中的)

    可以通过dbms_rowid这个包来转换我们的rowid成不同组成部分:

dbms_rowid.rowid_object(rowid)---> 32bit data_object# dbms_rowid.rowid_relative_fno(rowid)---> 10bit rfile# dbms_rowid.rowid_block_number(rowid)---> 22bit block# dbms_rowid.rowid_row_number(rowid)---> 16bit row#

三.与rowid相关知识点

 rdba(Tablespace relative database block address)就是rowid中的rfile#+block#.

 dba一般指绝对数据块地址。如果数据文件超过>=1024即2的10次方的话,仅用绝对dba在内部没办法表示的,内部一般是用rdba来表示,它限定了某个表空间

四.测试

  dba_objects.object_id 和 dba_objects.data_object_id :在对象建立当初,这两个id是一样的,前者代表的是这个对象的名字的id,是不会有变化的。即使你给这个表改一下名字,也不会有变化;后者,(也就是ROWID中的前六位代表的位置)是数据对象的位置(数据段)一个编号。如果把这个表换一个表空间,这个编号就会变化,同时rowid也会变化。

 1 SQL> create table t(id number,name varchar2(32)); 2 SQL> insert into t(id,name) values(0,yy); 3 SQL> commit; 4 SQL> select rowid,t.* from t; 5  6 ROWID                      ID NAME 7 ------------------ ---------- -------------------------------- 8 AAAWSPAABAAAYaxAAA          0 yy 9 10 SQL> select  dbms_rowid.rowid_object(rowid) object_id from t;11 12  OBJECT_ID13 ----------14      9127915 16 SQL>17 18 19 SQL> Select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE  20   2  From dba_objects 21   3  Where object_name=T;22 23 OWNER        OBJECT_NAME    OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE24 ------------ ----------     --------- -------------- ----------25 SYS          T              91279     91279          TABLE26 27 28 SQL>29 30 --改变表空间,即改变DATA_OBJECT_ID31 SQL> alter table t move tablespace TABROWID;32 33 SQL> Select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE  34   2  From dba_objects 35   3  Where object_name=T;36 37 OWNER      OBJECT_NAM  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE38 ---------- ---------- ---------- -------------- -------------------39 SYS        T          91279      91280          TABLE40 41 SQL>42 43 ----查看rowid是否变化:变化44 SQL> select  dbms_rowid.rowid_object(rowid) DATA_OBJECT_ID object_id from t;45 46 DATA_OBJECT_ID47 ----------48      9128049 SQL> 

结论:rowid中的数据对象编号对应dba_objects.DATA_OBJECT_ID

 

需要注意的是:当数据库文件超过1024个文件数,如何查找数据块所在文件号

 1 --根据表空间名、REL_FNO确定数据块所在文件file_id 2 1.查看数据块的REL_FNO,BLOCKNO 3     SELECT 4         dbms_rowid.rowid_relative_fno(rowid) REL_FNO, 5         dbms_rowid.rowid_block_number(rowid) BLOCKNO 6     FROM TEST_OBJECTS1  7     WHERE ROWNUM < 10; 8  9 2.确定文件编号file_id10 select segment_name,relative_fno,file_id11 from dba_extents 12 where segment_name=TEST_OBJECTS1 and relative_fno=&REL_FNO(第一个sql查询出的值)

 

Oracle rowid