技术活动
CUUG学员就业信息
学员感言、就业资讯
报名热线
文档
当前您的位置:首页 > 技术活动 > 技术中心 > 文档
Oracle ROWID-CUUG

  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

  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

  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 &n,bsp;

  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