设为首页 收藏本站
查看: 2838|回复: 0

[经验分享] Oracle ROWID-Oracle之路

[复制链接]

尚未签到

发表于 2018-9-14 09:32:58 | 显示全部楼层 |阅读模式
  ROWID 是一个类似于rownum的伪列,用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即
  被确定且唯一。而对于聚簇表,由于聚簇特性,不同表上的记录由于存储在相同的簇上,因此会拥有相同的ROWID。数据库的大多数操作都是通
  过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。下面将给出ROWID的相关描述。
  一、ROWID的特性组成及用途
  1、特性
  相对唯一性(聚簇表上不唯一)
  一旦确定,不可随意更改
  使用10个字节存储(扩展rowid),显示为18位的字符串
  特殊情况下,ROWID会发生变化(如下列情形)
  表的导入导出操作

  >
  >  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
  -----------------------------------------------------------------------------------

  |>  -----------------------------------------------------------------------------------
  |   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>  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
  ---------------------------------------------------------------------------------------

  |>  ---------------------------------------------------------------------------------------
  |   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>  ---------------------------------------------------
  2 - access("DEPTNO"=30)
  Statistics
  ----------------------------------------------------------
  1  recursive calls
  0  db block gets
  2  consistent gets                          -->consistent gets比直接使用rowid多一次(即执行了索引扫描)
  0  physical reads

  0  redo>  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>>
  Table>  SQL> select rowid,t.* from t;          -->使用alter table tab_name move命令后,rowid发生变化
  -->其他导致rowid变化的情形演示略
  ROWID                      ID RID
  ------------------ ---------- ------------------
  AAAPQ/AAFAAAAt8AAA          1 AAAPQ+AAFAAAAt4AAA
  oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-581974-1-1.html 上篇帖子: oracle char nchar varchar varchar2 nvarchar2 下篇帖子: oracle技术之进程、会话、连接之间的差异
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表