日期:2014-05-16  浏览次数:20303 次

理解oracle ROWID

    数据存放在数据文件中,其属性会随着存储而确定,这些属性包括:在哪个数据文件?属于哪个对象?所在的数据块?行号? 将这些属性合并起来就构成了oracle的ROWID。

   

    所以,rowid详细的记录了数据在磁盘上的位置。简单讲,也叫行地址

   

    ROWID可分:物理和逻辑。除了IOT使用逻辑ROWID,其他类型的表使用物理ROWID。

 

    ROWID也可分:受限和扩展。8i之后使用扩展rowid。

 

    下面介绍扩展rowid。

 

    扩展rowid,采用64位编码,按6、3开。

 

    例子:

SQL> show user
USER 为 "HR"
SQL> drop table t1 purge;
drop table t1 purge
           *
第 1 行出现错误:
ORA-00942: 表或视图不存在


SQL> create table  t1 (id number,name varchar2(20));

表已创建。

SQL> insert into t1 values(1,'a');

已创建 1 行。

SQL> insert into t1 values(2,'b');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select rowid,t1.* from t1;

ROWID                      ID NAME
------------------ ---------- ----------------------------------------
AAANFgAAEAAAAHYAAA          1 a
AAANFgAAEAAAAHYAAB          2 b


                                                  ROWID的64个编码表

base64表示 数字顺序
A~Z 0~25
a~z 26~51
0~9 52~61
+ 62
/ 63

 

    id=1其对应的rowid为:AAANFg     AAE     AAAAHY     AAA

    AAANFg

    段编号(对应dba_data_files的data_object_id)。请注意和object_id区别开。object_id是对象编号,唯一标识对象,是对象的身份证(与段编号不同:段一定是对象,但对象不一定是段)。物理位置改变,如移动表空间,则data_object_id便也改变了。对象名改变,则不影响object_id。truncate也会改变段编号,因为truncate是DDL语句,将表的元数据从数据字典删掉,同时退掉HWM,但数据是没有删掉的。

    从上表可得:A=0     N=13   F=5   g=32

   

SQL> select 13*power(64,2)+5*64+32 from dual;

13*POWER(64,2)+5*64+32
----------------------
                 53600


    我们也可以通过dbms_rowid这个包来求:

 

SQL> select dbms_rowid.rowid_object('AAANFgAAEAAAAHYAAA') from dual;

DBMS_ROWID.ROWID_OBJECT('AAANFGAAEAAAAHYAAA')
---------------------------------------------
                                        53600


 

    AAE