数据存放在数据文件中,其属性会随着存储而确定,这些属性包括:在哪个数据文件?属于哪个对象?所在的数据块?行号? 将这些属性合并起来就构成了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
相对文件编号 (relative_fno),表空间级别的。注意和绝对文件编号的区别(file_id),数据库级别的。
AAAAHY
数据块号
AAA
行号
ROWID在oracle中的地位不言而喻。索引的本质,也就是利用ROWID,因为索引保存了rowid,根据rowid再到数据表中定位记录。想象一本书,索引是目录,书的内容是数据,那么rowid便是联系目录和内容的那一个“页码”。