oracle中中rowid,oracle中的Rowid和Urowid

Oracle使用rowid数据类型存储行地址,rowid可以分成两种,分别适于不同的对像

Physical rowids:存储ordinary table,clustered table,table partition and subpartition,indexe,index partition and subpartition

Logical rowids :存储IOT的行地址

另一种rowid类型叫universal rowed(UROWID),支持上述physical rowid和logical rowed,并且支持非oracle table,即支持所有类型的rowid,但COMPATIBLE必须在8.1或以上.

1.1 ROWID伪列

每个表在oracle内部都有一个ROWID伪列,它在所有sql中无法显示,不占存储空间;它用于从表中查询行的地址或者在where中进行参照,一个例子如下:

SELECT ROWID, last_name FROM employees;

Oracle内部使用保留在ROWID伪列中的值构建索引结构

再次强调一次,rowid伪列不存储在数据库中,它不是数据库数据,这是从database及table的逻辑结构来说的,事实上,在物理结构上,每行由一个或多个row pieces组成,每个row piece的头部包含了这个piece的address,即rowid.从这个意义上来说,rowid还是占了磁盘空间的.

我们在创建表时,可以为列指定为rowid数据类型,但oracle并不保证列中的数据是合法的rowid值,必须由应用程序来保证,另外,类型为rowid的列需要6 bytes存储数据

1.2, physical rowids

只在行存在,它的物理地址rowid就不会变化,除非export/import,根据rowid可以直接定位到block去fetch数据,所以physical兼具有高稳定(stability)和高性能(performance)的特点.

这里要注意一点,对于clustered table来说,根据它的存储特点,在同一个block中的不同table的行可能具有同一个rowid;而nonclustered table,每一行或初始行片(initial row piece)都有唯一的rowid

要注意rowid的地址固定的特点,在一个block的某一行被delete并commit后,它占据的address可以被其它事务新insert的行重用.

Physical rowid可以是下面任一一种格式:

1) Extended rowid

使用表空间相关的数据块地址,8i及以上使用这种格式

2) Restricted rowid

使用数据库范围的数据址地址,oracle 7或更早前的版本使用

1.2.1extened rowid

扩展行地址是64编码的物理地址,编码字符是A-Z, a-z, 0-9, +,and/.

由4部分组成OOOOOOFFFBBBBBBRRR (obj#file#block#row#)

OOOOOO -–data object number

FFF –-表空间相对的数据文件号

BBBBBB –-块号

RRR ---行号

注意不是16进制表示

SQL> select rowid,name from obj$ where rownum<=10;

ROWIDNAME

------------------ ------------------------------

AAAAASAABAAAAB6ABc ACCESS$

AAAAASAABAAAC1QAAK AGGXMLIMP

AAAAASAABAAAC1QAAL AGGXQIMP

AAAAASAABAAAGiRAAI ALERT_QT

AAAAASAABAAAGiRAAh ALERT_QUE

AAAAASAABAAAGujAAo ALERT_QUE$1

AAAAASAABAAAGujAAp ALERT_QUE$1

AAAAASAABAAAGiRAAf ALERT_QUE_N

AAAAASAABAAAGiRAAe ALERT_QUE_R

AAAAASAABAAAGiRAAG ALERT_TYPE

我们可以使用dbms_rowid从extened rowid中抽取各部分信息,或者将extened rowid转换成restricted rowed,详细的信息参见sys.dbms_rowid的规范

#根据rowid抽块对像编号

SQL> select dbms_rowid.rowid_object('AAAAASAABAAAGiRAAG') obj#from dual;

OBJ#

----------

18

#根据rowid抽取表空间相对文件号

SQL> select dbms_rowid.rowid_relative_fno('AAAAASAABAAAGiRAAG') rfile# from dual;

RFILE#

----------

1

#根据rowid抽取块号

SQL> select dbms_rowid.ROWID_BLOCK_NUMBER('AAAAASAABAAAGiRAAG') block# from dual;

BLOCK#

----------

26769

#根据rowid抽取行号

SQL> select dbms_rowid.rowid_row_number('AAAAASAABAAAGiRAAG') row#from dual;

ROW#

----------

6

#将extended rowid转换成为restricted rowid

SQL> select dbms_rowid.rowid_to_restricted('AAAAASAABAAAGiRAAG',0) restricted_rowidfrom dual;

RESTRICTED_ROWID

------------------

00006891.0006.0001

1.2.2restricted rowid

限制地址行号与扩展地址行号编码方式不一样,它在内部使用二进制方式表示,当用select查询时,会转换成varchar2/16进制的混合形式,它的组织方式如下:

BBBBBBBB.RRRR.FFFF(block#.row#.file#)

注意,这里的文件号是绝对文件号,而extended rowid中是相对文件号(相对表空间)

Restricted rowid中不再有object number,因为从绝对文件号可以唯一确定数据块

样例可以参考前面的00006891.0006.0001

另外请注意,块中的行号是从0开始

除了用dbms_rowid来抽取rowid的不同部分外,也可以用substr

#extended rowid

SQL> SELECT ROWID,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值