说说Oracle的rowid

说说Oracle的rowid,第1张

在Oracle中rowid唯一标识每条记录所在的位置 它作为一个伪列在查询中出现

select rowid id

from test_table

where rownum<=

ROWID                      ID

AAAVcbAAPAAAAALAAA         

AAAVcbAAPAAAAALAAB         

AAAVcbAAPAAAAALAAC         

AAAVcbAAPAAAAALAAD         

AAAVcbAAPAAAAALAAE         

AAAVcbAAPAAAAALAAF         

AAAVcbAAPAAAAALAAG         

AAAVcbAAPAAAAALAAH         

AAAVcbAAPAAAAALAAI         

AAAVcbAAPAAAAALAAJ        

rowid是由 个字符组成分 个部分 分别是

个字符的对象编号 个字符的文件号 个字符的块编号 个字符的行编号

每一个字符的取值范围以及对应的数值是

| A|  |    | a| |    | | |

| B|  |    | b| |    | | |

| C|  |    | c| |    | | |

| D|  |    | d| |    | | |

| E|  |    | e| |    | | |

| F|  |    | f| |    | | |

| G|  |    | g| |    | | |

| H|  |    | h| |    | | |

| I|  |    | i| |    | | |

| J|  |    | j| |    | | |

| K| |    | k| |    | +| |

| L| |    | l| |    | /| |

| M| |    | m| |    |  |   |

| N| |    | n| |    |  |   |

| O| |    | o| |    |  |   |

| P| |    | p| |    |  |   |

| Q| |    | q| |    |  |   |

| R| |    | r| |    |  |   |

| S| |    | s| |    |  |   |

| T| |    | t| |    |  |   |

| U| |    | u| |    |  |   |

| V| |    | v| |    |  |   |

| W| |    | w| |    |  |   |

| X| |    | x| |    |  |   |

| Y| |    | y| |    |  |   |

| Z| |    | z| |    |  |   |

可以看到rowid是一个 进制的表示方式 利用上述对应表即可计算出

对象编号 AAAVcb  =

文件号 AAP =

块号 AAAAAL =

行号 AAA~AAJ = ~

进制的转换完全可以交给机器去做 Oracle也是这么认为的 于是提供了一个叫做dbms_rowid的包 它包含了一系列的方法 我们借助这个包就可完成上述的工作了

select rowid

   substr(rowid ) || : || dbms_rowid rowid_object(rowid)       数据对象编号/object_id

   substr(rowid ) || : || dbms_rowid rowid_relative_fno(rowid) 文件编号/file_id

   substr(rowid )|| : || dbms_rowid rowid_block_number(rowid) 块编号/block_id

   substr(rowid )|| : || dbms_rowid ROWID_ROW_NUMBER(rowid)   行编号/row_num

from test_table

where rownum<=

ROWID              数据对象编号/object_id    文件编号/file_id     块编号/block_id      行编号/row_num

AAAVcbAAPAAAAALAAA AAAVcb :             AAP :              AAAAAL :           AAA :

AAAVcbAAPAAAAALAAB AAAVcb :             AAP :              AAAAAL :           AAB :

AAAVcbAAPAAAAALAAC AAAVcb :             AAP :              AAAAAL :           AAC :

AAAVcbAAPAAAAALAAD AAAVcb :             AAP :              AAAAAL :           AAD :

AAAVcbAAPAAAAALAAE AAAVcb :             AAP :              AAAAAL :           AAE :

AAAVcbAAPAAAAALAAF AAAVcb :             AAP :              AAAAAL :           AAF :

AAAVcbAAPAAAAALAAG AAAVcb :             AAP :              AAAAAL :           AAG :

AAAVcbAAPAAAAALAAH AAAVcb :             AAP :              AAAAAL :           AAH :

AAAVcbAAPAAAAALAAI AAAVcb :             AAP :              AAAAAL :           AAI :

AAAVcbAAPAAAAALAAJ AAAVcb :             AAP :              AAAAAL :           AAJ :

这个结果对不对呢?我们可以这样验证 注意 以下查询需要DBA权限

首先是object_id

select

   owner object_name object_id

from dba_objects

where object_name= TEST_TABLE

OWNER      OBJECT_NAME           OBJECT_ID

TEST       TEST_TABLE               

然后是文件编号和块编号

select

   owner segment_name segment_type extent_id

   file_id block_id blocks bytes

from dba_extents

where segment_name= TEST_TABLE

OWNER  SEGMENT_NAME  SEGMENT_TYPE   EXTENT_ID  FILE_ID  BLOCK_ID  BLOCKS  BYTES

TEST   TEST_TABLE    TABLE                                          

TEST   TEST_TABLE    TABLE                                         

编号为 的块落在了编号为 的exntent上 只能说是验证了一半 接下来我们将数据块dump出来看看 不过做之前先为这一行打上 标记 看以下过程

test$logdw@logdw SQL>select rowid t * from test_table t where rownum<=

ROWID                      ID DATA

AAAVcbAAPAAAAALAAA                                        Q

AAAVcbAAPAAAAALAAB                                        Q

AAAVcbAAPAAAAALAAC                                        Q

AAAVcbAAPAAAAALAAD                                        Q

AAAVcbAAPAAAAALAAE                                        Q

rows selected

test$logdw@logdw SQL>update test_table set data=lpad( killkill ) where id=

row updated

test$logdw@logdw SQL>select rowid t * from test_table t where rownum<=

ROWID                      ID DATA

AAAVcbAAPAAAAALAAA                                 killkill

AAAVcbAAPAAAAALAAB                                        Q

AAAVcbAAPAAAAALAAC                                        Q

AAAVcbAAPAAAAALAAD                                        Q

AAAVcbAAPAAAAALAAE                                        Q

rows selected

test$logdw@logdw SQL>mit

做好了 标记 可以dump数据块了

sys$logdw@logdw SQL>select get_trace_name() from dual

GET_TRACE_NAME()

/u /app/oracle/diag/rdbms/logdw/logdw/trace/logdw_ora_ trc

sys$logdw@logdw SQL>alter system dump datafile block

System altered

打开trc文件 摘录如下

Start dump data blocks tsn: file#: minblk maxblk

Dump of memory from x A F A to x A F A

A F F C B   [             kil]

A F F C B C C C E C   [lkill     ]

block_row_dump:

tab row @ x ac

tl: fb: H FL lb: x   cc:

col  : [ ]  c

col  : [ ]

  b c

  c b c c

lishixinzhi/Article/program/Oracle/201311/17417

rowid: 表示了记录的物理地址(不一定是连续的) 是唯一存在的

rownum:表示了记录的行号(是连续的)

两者没有必然的联系,所以rowid排在前面的行,rownum不一定排在前面。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9565415.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存