Oracle ROWID

ROWID 是一个类似于rownum的伪列,用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即
被确定且唯一。而对于聚簇表,由于聚簇特性,不同表上的记录由于存储在相同的簇上,因此会拥有相同的ROWID。数据库的大多数操作都是通
过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。下面将给出ROWID的相关描述。

一、ROWID的特性组成及用途
1、特性
相对唯一性(聚簇表上不唯一)
一旦确定,不可随意更改
使用10个字节存储(扩展rowid),显示为18位的字符串
特殊情况下,ROWID会发生变化(如下列情形)
表的导入导出操作
alter table tab_name move
alter table tab_name shrink space
flashback table tab_name
拆分分区表
分区表上更新一个值后记录被移入到新分区
合并两个分区
2、组成(扩展ROWID)
数据库对象的对象编号
数据库对象所在文件的文件编号
数据库对象上块的编号
块上的行编号(起始值为0)
3、用途
快速定位单行记录
展示行在表上如何存储
表上的一行的唯一标识符
用作数据类型 column_name rowid
4、限制rowid,扩展rowid
限制rowid用于早期Oracle版本(Oracle 8 以前),rowid由file#+block#+row#组成,占用6个bytes的空间
扩展rowid,由data_object_id#+rfile#+block#+row#组成,占用10个bytes的空间

二、ROWID的格式

SQL> select rowid,t.* from dept t where t.deptno=10; ROWID DEPTNO DNAME LOC ------------------ ---------- -------------- ------------- AAAO0fAAFAAAAlmAAA 10 ACCOUNTING NEW YORK /* AAAO0f - AAF - AAAAlm - AAA 对象号(6个字符) 文件号(3个字符) 块号(6个字符) 行号(3个字符) */

三、查看ROWID信息及相关演示
1、查看堆表上rowid及获取rowid信息

SQL> select rowid,dept.* from dept ; -->查看表dept中所有记录的rowid ROWID DEPTNO DNAME LOC ------------------ ---------- -------------- ------------- AAAO0fAAFAAAAlmAAA 10 ACCOUNTING NEW YORK AAAO0fAAFAAAAlmAAB 20 RESEARCH DALLAS AAAO0fAAFAAAAlmAAC 30 SALES CHICAGO AAAO0fAAFAAAAlmAAD 40 OPERATIONS BOSTON /**************************************************/ /* Author: Robinson Cheng */ /* Blog: http://blog.csdn.net/robinson_0612 */ /* MSN: [email protected] */ /* QQ: 645746311 */ /**************************************************/ SQL> select object_name,object_id from dba_objects where object_name='DEPT' and owner='SCOTT';-->查看对象id OBJECT_NAME OBJECT_ID -------------------- ---------- DEPT 60703 SQL> select dbms_rowid.rowid_object(rowid) object_id, -->使用dbms_rowid包获得rowid的十进制信息 2 dbms_rowid.rowid_relative_fno(rowid) file_id, 3 dbms_rowid.rowid_block_number(rowid) block_id, 4 dbms_rowid.rowid_row_number(rowid) num 5 from dept; OBJECT_ID FILE_ID BLOCK_ID NUM -->此处可以看到对应的对象号,文件号,块号以及行号 ---------- ---------- ---------- ---------- 60703 5 2406 0 60703 5 2406 1 60703 5 2406 2 60703 5 2406 3 SQL> col file_name format a50 SQL> select file_id,file_name from dba_data_files where file_id=5; -->通过文件id获得对象所在数据文件的位置 FILE_ID FILE_NAME ---------- -------------------------------------------------- 5 /u02/database/CNMMBO/oradata/CNMMBO_system_tbl.dbf SQL> select rowid, -->这个查询按照rowid的定义格式进行分离rowid 2 substr(rowid,1,6) "object", 3 substr(rowid,7,3) "file", 4 substr(rowid,10,6) "block", 5 substr(rowid,16,3) "row" 6 from dept; ROWID object file block row ------------------ ------------------ --------- ------------------ --------- AAAO0fAAFAAAAlmAAA AAAO0f AAF AAAAlm AAA AAAO0fAAFAAAAlmAAB AAAO0f AAF AAAAlm AAB AAAO0fAAFAAAAlmAAC AAAO0f AAF AAAAlm AAC AAAO0fAAFAAAAlmAAD AAAO0f AAF AAAAlm AAD

2、查看簇表上的rowid 有关簇表请参考:簇表及簇表管理(Index clustered tables)

SQL> select table_name,tablespace_name,cluster_name,status,pct_free from 2 dba_tables where owner = 'ROBINSON'; -->列cluster_name上包含簇名,这两个表为簇表 TABLE_NAME TABLESPACE_NAME CLUSTER_NAME STATUS PCT_FREE ---------------- ----------------- ------------------------------ -------- ---------- EMP TBS_TMP EMP_DEPT_CLUSTER VALID 0 DEPT TBS_TMP EMP_DEPT_CLUSTER VALID 0 SQL> select rowid dept_rowid,deptno from dept; -->查看dept上的rowid DEPT_ROWID DEPTNO ------------------ ---------- AAAPRAAAsAABgDgAAA 10 AAAPRAAAsAABgDgAAB 20 AAAPRAAAsAABgDgAAC 30 AAAPRAAAsAABgDgAAD 40 SQL> select d.deptno,e.rowid emp_rowid,e.ename -->查看emp上的rowid,存在与dept表相同的rowid 2 from dept d join emp e 3 on d.rowid=e.rowid; DEPTNO EMP_ROWID ENAME ---------- ------------------ ---------- 10 AAAPRAAAsAABgDgAAA CLARK 20 AAAPRAAAsAABgDgAAB KING 30 AAAPRAAAsAABgDgAAC MILLER 40 AAAPRAAAsAABgDgAAD SMITH SQL> select * from dept where rowid='AAAPRAAAsAABgDgAAA'; -->使用相同的rowid访问不同的表 DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK SQL> select * from emp where rowid='AAAPRAAAsAABgDgAAA'; -->使用相同的rowid访问不同的表 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7782 CLARK MANAGER 7839 09-JUN-81 4900 10

3、使用rowid访问数据的情形

SQL> set autotrace on; SQL> select * from dept where rowid='AAAO0fAAFAAAAlmAAC'; -->使用rowid访问数据行 DEPTNO DNAME LOC ---------- -------------- ------------- 30 SALES CHICAGO Execution Plan -------------------------------------------- -->执行计划中为TABLE ACCESS BY USER ROWID访问方式 Plan hash value: 3453257278 ----------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 1 (0)| 00:00:01 | | 1 | TABLE ACCESS BY USER ROWID| DEPT | 1 | 20 | 1 (0)| 00:00:01 | ----------------------------------------------------------------------------------- Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 1 consistent gets -->此处的consistent gets值为1 0 physical reads 0 redo size 651 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> select * from dept where deptno=30; -->使用字面量访问行记录 DEPTNO DNAME LOC ---------- -------------- ------------- 30 SALES CHICAGO Execution Plan ------------------------------------- -->执行计划先INDEX UNIQUE SCAN,然后根据索引叶结点上的rowid访问数据 Plan hash value: 2852011669 --------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 1 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 20 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 | --------------------------------------------------------------------------------------- Predicate Information (identified by operation id): -->包含了谓词信息 --------------------------------------------------- 2 - access("DEPTNO"=30) Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 2 consistent gets -->consistent gets比直接使用rowid多一次(即执行了索引扫描) 0 physical reads 0 redo size 651 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed

4、使用rowid数据类型

SQL> create table t(id number,rid rowid); -->创建包含rowid类型的表 Table created. SQL> insert into t(id) values(1); -->新增一条记录 1 row created. SQL> update t set rid=t.rowid ; -->更新rowid类型的列 1 row updated. SQL> select rowid,t.* from t; -->rid列于rowid列值相同 ROWID ID RID ------------------ ---------- ------------------ AAAPQ+AAFAAAAt4AAA 1 AAAPQ+AAFAAAAt4AAA

5、rowid变化的情形

SQL> alter table t move; Table altered. SQL> select rowid,t.* from t; -->使用alter table tab_name move命令后,rowid发生变化 -->其他导致rowid变化的情形演示略 ROWID ID RID ------------------ ---------- ------------------ AAAPQ/AAFAAAAt8AAA 1 AAAPQ+AAFAAAAt4AAA



你可能感兴趣的:(Oracle ROWID)