zoukankan      html  css  js  c++  java
  • Oracle rowid

    一.Rowid

      rowid是伪列(pseudocolumn),伪劣的意思是实际上这一列本身在数据字典中并不存在,在查询结果输出时它被构造出来的。

      rowid并不会真正存在于表的data block中,但是他会存在于index当中,用来通过rowid来寻找表中的行数据

    二.Rowid的结构

      限制rowid:用于早期Oracle版本(Oracle 8 以前),rowid由(10 bit)file#+(22 bit)block#+(16 bit)row#组成,占用6个bytes的空间

      注:file#为10位,故整个数据库最多只能有的2^10-2=1022个数据文件(去掉全0和全1)

      扩展rowid:由data_object#+rfile#+block#+row#组成,占用10个bytes的空间,显示为18位的字符串

      扩展rowid包含下列组成元素:

    1. 数据对象编号(32 bit):对应dba_objects.data_object_id.此编号确定所属表空间,因为一个段对象只属于一个表空间                           
    2. 相对文件编号(10 bit):对应dba_extents.relative_fno.此编号对于表空间中的每个数据文件是唯一的,故每个表空间中可以最多有2^10-2个数据文件
    3. 块编号(22 bit):表示包含此行的块在数据文件中的位置
    4. 行编号(16 bit):标识块头中行目录位置的位置

      定位一行记录的顺序是:数据对象(表空间)-->数据文件(此表空间中的)-->块编号(此数据文件中的)-->定位行(此块中的)

        可以通过dbms_rowid这个包来转换我们的rowid成不同组成部分:

    dbms_rowid.rowid_object(rowid)---> 32bit data_object# 
    dbms_rowid.rowid_relative_fno(rowid)---> 10bit rfile# 
    dbms_rowid.rowid_block_number(rowid)---> 22bit block# 
    dbms_rowid.rowid_row_number(rowid)---> 16bit row#

    三.与rowid相关知识点

     rdba(Tablespace relative database block address)就是rowid中的rfile#+block#.

     dba一般指绝对数据块地址。如果数据文件超过>=1024即2的10次方的话,仅用绝对dba在内部没办法表示的,内部一般是用rdba来表示,它限定了某个表空间

    四.测试

      dba_objects.object_id 和 dba_objects.data_object_id :在对象建立当初,这两个id是一样的,前者代表的是这个对象的名字的id,是不会有变化的。即使你给这个表改一下名字,也不会有变化;后者,(也就是ROWID中的前六位代表的位置)是数据对象的位置(数据段)一个编号。如果把这个表换一个表空间,这个编号就会变化,同时rowid也会变化。

     1 SQL> create table t(id number,name varchar2(32));
     2 SQL> insert into t(id,name) values(0,'yy');
     3 SQL> commit;
     4 SQL> select rowid,t.* from t;
     5 
     6 ROWID                      ID NAME
     7 ------------------ ---------- --------------------------------
     8 AAAWSPAABAAAYaxAAA          0 yy
     9 
    10 SQL> select  dbms_rowid.rowid_object(rowid) object_id from t;
    11 
    12  OBJECT_ID
    13 ----------
    14      91279
    15 
    16 SQL>
    17 
    18 
    19 SQL> Select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE  
    20   2  From dba_objects 
    21   3  Where object_name='T';
    22 
    23 OWNER        OBJECT_NAME    OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
    24 ------------ ----------     --------- -------------- ----------
    25 SYS          T              91279     91279          TABLE
    26 
    27 
    28 SQL>
    29 
    30 --改变表空间,即改变DATA_OBJECT_ID
    31 SQL> alter table t move tablespace TABROWID;
    32 
    33 SQL> Select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE  
    34   2  From dba_objects 
    35   3  Where object_name='T';
    36 
    37 OWNER      OBJECT_NAM  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
    38 ---------- ---------- ---------- -------------- -------------------
    39 SYS        T          91279      91280          TABLE
    40 
    41 SQL>
    42 
    43 ----查看rowid是否变化:变化
    44 SQL> select  dbms_rowid.rowid_object(rowid) DATA_OBJECT_ID object_id from t;
    45 
    46 DATA_OBJECT_ID
    47 ----------
    48      91280
    49 SQL> 

    结论:rowid中的数据对象编号对应dba_objects.DATA_OBJECT_ID

    需要注意的是:当数据库文件超过1024个文件数,如何查找数据块所在文件号

     1 --根据表空间名、REL_FNO确定数据块所在文件file_id
     2 1.查看数据块的REL_FNO,BLOCKNO
     3     SELECT
     4         dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
     5         dbms_rowid.rowid_block_number(rowid) BLOCKNO
     6     FROM TEST_OBJECTS1 
     7     WHERE ROWNUM < 10;
     8 
     9 2.确定文件编号file_id
    10 select segment_name,relative_fno,file_id
    11 from dba_extents 
    12 where segment_name='TEST_OBJECTS1' and relative_fno=&REL_FNO(第一个sql查询出的值)
  • 相关阅读:
    第二阶段冲刺04
    找水王
    第二阶段冲刺03
    第二阶段冲刺02
    第二阶段冲刺01
    学习进度12
    梦断代码阅读笔记07
    第一阶段意见评论
    学习进度11
    求素数p的原根
  • 原文地址:https://www.cnblogs.com/polestar/p/4225637.html
Copyright © 2011-2022 走看看