说说Oracle的rowid

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了说说Oracle的rowid相关的知识,希望对你有一定的参考价值。

参考技术A

  在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

informix/oracle rowid 问题

rowid是怎样的生成机制,比如,当一个表是新表,我插入数据时,rowid是连续的,如果我删除了几条记录,再插入数据,rowid是选择递增还是使用以前被删除记录的rowid?
我在插入记录时,怎么设置插入记录的rowid?

参考技术A rowid是Oracle自动生成的,不用人为的插入。 参考技术B 递增,ROWID无需人为干预。 参考技术C for informix:
在未做分片的表中,数据库按照表在DBS中的物理地址作为ROWID,此地址在DBS中是固定并且唯一的,所以,未分片表,数据库系统默认为其生成一个隐藏字段叫rowid。
而对于分片表,由于不同的记录在不同的DBS中可能有相同的物理地址,所以数据库没有为分片表默认生成ROWID,如果想在这些表上使用ROWID,则需要执行下面的操作:
ALTER TABLE table_name ADD ROWIDS;
或在建表时使用 WITH ROWIDS表达式
ps:建议在建完ROWID之后,对ROWID做一下统计更新:
update statistics high for table table_name(rowid)

以上是关于说说Oracle的rowid的主要内容,如果未能解决你的问题,请参考以下文章

简单说说oracle的概要文件。

说说 Oracle 的 NVL 与 NVL2 函数

面试oracle 经常问的一个问题- 事务

2018.5.12说说反射的用途及实现------要再花费时间加强理解

说说数据库事务开发(上)

[转]Oracle hang分析