Oracle rowid详解
- 格式:doc
- 大小:96.00 KB
- 文档页数:11
oracle rowid排序规则摘要:1.简介2.Oracle Rowid 的作用3.Oracle Rowid 的排序规则4.总结正文:1.简介Oracle 数据库是一种关系型数据库管理系统,广泛应用于各种企业和组织的数据存储和管理。
在Oracle 数据库中,Rowid 是一个用于唯一标识表中每一行的元数据,类似于身份证号,具有唯一性。
Rowid 对于数据库性能优化和数据查询具有重要意义。
本文将详细介绍Oracle Rowid 的排序规则。
2.Oracle Rowid 的作用Oracle Rowid 主要用于以下几个方面:(1)唯一标识表中的每一行数据。
(2)在数据库复制和数据移动过程中,作为源数据和目标数据之间的映射。
(3)在数据库连接和会话管理中,作为识别不同会话的依据。
(4)在分布式数据库环境中,作为协调不同节点之间数据访问的标识。
3.Oracle Rowid 的排序规则Oracle Rowid 的排序规则主要遵循以下几点:(1)在同一行数据中,Rowid 是单调递增的。
也就是说,当一条数据被更新或者插入时,它的Rowid 会比之前的Rowid 大。
(2)不同行的Rowid 之间没有固定的顺序。
也就是说,Rowid 之间不能直接比较大小,不能用Rowid 来对数据进行排序。
(3)Rowid 的生成方式有多种,包括基于行号、基于时间戳、基于分布式事务ID 等。
不同的生成方式可能影响Rowid 的排序规则。
(4)在某些特定场景下,例如在使用数据库连接池时,Oracle 会为连接池中的每个连接分配一个唯一的Rowid,以区分不同的连接。
4.总结Oracle Rowid 是数据库中非常重要的元数据,用于唯一标识表中的每一行数据。
虽然Rowid 具有单调递增的特性,但它不能直接用于数据排序。
在实际应用中,需要根据业务需求选择合适的排序方式。
oracle中rowid的用法Oracle数据库中的ROWID,是由Oracle内部用来唯一标识一行数据的一种方式。
在Oracle数据库的某些操作中,使用ROWID可以帮助我们更快速准确的访问和处理数据。
下面将详细介绍ROWID的用法和应用场景。
一、ROWID的使用方法1.基本方法:在SQL中使用ROWID查询在SQL中,通过查询语句直接使用ROWID来定位数据行。
例如:SELECT * FROM table WHERE ROWID='AAAR3u'+3gAAAQ7AAA';注意:需要使用单引号将ROWID的值括起来,并在其前面加上'AAAR3u'+3gAAAQ7AAA'。
这是由于ROWID值含有特殊字符,所以需要进行转义。
2. DML 操作ROWID也可以用于 UPDATE、DELETE 操作中,将其作为 WHERE 子句的条件。
例如:UPDATE table SET column1=value WHEREROWID='AAAR3u'+3gAAAQ7AAA';二、ROWID应用场景1. 存储大量的数据当存储大量数据时,ROWID可用于更快地定位和处理数据。
在这种情况下,我们可以利用 ROWID 执行快速和有效的操作。
在进行大量数据的操作时,ROWID 可以按照最小的 I/O 开销进行访问。
2. 分区表当使用分区表时,ROWID可用于确定特定的数据行是否属于某个特定的分区。
在存在多个分区的情况下,我们可以使用 ROWID 快速找到特定分区中的数据行。
3. 高速查询在某些情况下,ROWID也可以帮助我们实现高速查询,尤其在有大量数据行的表中,使用 ROWID 和基于 ROWID 的索引,可以更快速准确的检索到数据。
总结在Oracle数据库中,ROWID是一种唯一标识一行数据的方式,我们可以通过在SQL中使用ROWID来定位或处理数据。
oracle执行计划解释一.相关概念1·rowid,伪列:就是系统自己给加上的,每个表都有一个伪列,并不是物理存在。
它不能被修改,删除,和添加,rowid在该行的生命周期是唯一的,如果向数据库插入一列,只会引起行的变化,但是rowid并不会变。
2·recursive sql概念:当用户执行一些SQL语句时,会自动执行一些额外的语句,我们把这些额外的SQL语句称为“recursive calls” 或者是“recursive sql statement”,当在执行一个DDL语句时,Oracle总会隐含的发出一些Recursiv sql语句,用于修改数据字典,如果数据字典没有在共享内存中,则就执行“resursive calls”,它会把数据字典从物理读取到共享内存。
当然DML和select语句都可能引起recursive SQL。
3·row source 行源:在查询中,由上一操作返回的符合条件的数据集,它可能是整个表,也可能是部分,当然也可以对2个表进行连接操作(join)最后得到的数据集4·predicate:一个查询中的where限制条件5·driving table 驱动表:该表又成为外层表,这个感念用于内嵌和HASH连接中,如果返回数据较大,会有负面影响,返回行数据较小的适合做驱动表6·probed table 被探查表:该表又称为内层表,我们在外层表中取得一条数据,在该表中寻找符合连接的条件的行。
7·组合索引(concatenated index)由多个列组成的索引,在组合索引中有一个重要的概念,就是引导索引,create index idx_tab on tab(col1,col2,col3),indx_tab则称为组合索引,col1则称为引导列在查询条件where后,必须使用引导索引,才会使用该组合索引8.可选择性(selectivity)比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。
首先来说一下rownum与rowid含义:顾名思义rownum就是行数/行号,而rowid就是编码/编号/唯一识别号,所以他是类似“AAAR8gAAEAAAAErAAK”的编号,注意他是没有先后顺序的,也就是说他和数据入库时间没有任何关系,打个比方:他就像磁盘、内存存储数据用的是16进制的地址一样。
他们都是伪列,可以理解成表中的一个列只是他们并不是你创建的。
同样是伪列区别是什么呢?rowid是你录入数据时有数据库自动为这条记录添加的唯一的18位编号是一个物理编号用于找到这条记录(顺便说一句这也是为什么数据优调的时候强调尽量使用rowid的原因),他是不会随着查询而改变的除非在表发生移动(比如表空间变化,数据导入/导出以后),才会发生变化。
rownum是根据sql查询后得到的结果自动加上去的,但是他却不受到sql中order by排序的影响,因为他和rowid的顺序一样是系统按照记录插入时的顺序给记录排的号(顺序的、无跳跃)。
但是如果你想让rownum和order by一样的顺序那么可以使用子查询,形如:select rownum,t.* from (select * from 表空间名 order by 字段名) t 这样的话rownum就是根据该字段进行排序的编号了,为什么会这样呢,本人理解:rownum是根据表记录输出的行号,与筛选语句、排序语句都无关所以当用子查询时等于生成了一个表于是就按照这张表从1开始排序了。
同样,也可以用下面要提得到的分析函数中的row_number() over(order by 需要排序的字段名)。
值得一提的是MSSQL是没有rownum和rowid的。
一,什么是伪列RowID?1,首先是一种数据类型,唯一标识一条记录物理位置的一个id,基于64位编码的18个字符显示。
2,未存储在表中,可以从表中查询,但不支持插入,更新,删除它们的值。
二,RowID的用途1,在开发中使用频率应该是挺多的,特别在一些update语句中使用更加频繁。
rowid原理oracle学习总结(一)---ROWID(转)文章分类:数据库关键字: oracle搞oracle都会经常碰到rowid,本文是笔者根据网上各位的文章,加上自己学习中的体会,总结而成。
一.rowid简介rowid就是唯一标志记录物理位置的一个id,在oracle 8版本以前,rowid由file#+block#+row#组成,占用6个bytes的空间,10 bit 的 file# ,22bit 的 block# ,16 bit 的 row#。
从oracle 8开始rowid变成了extend rowid,由data_object_id#+rfile#+block#+row#组成,占用10个bytes的空间, 32bit的 data_object_id#,10 bit 的 rfile#,22bit 的block#,16 bit 的 row#.由于rowid的组成从file#变成了rfile#,所以数据文件数的限制也从整个库不能超过1023个变成了每个表空间不能超过1023个数据文件。
说了rowid的组成,那么我们再来看看rowid在索引里面占用的字节数又是什么样子的。
在oracle 8以前索引中存储的rowid 占用字节数也是6bytes,在oracle8之后,虽然oracle使用了extend rowid,但是在普通索引里面依然存储了bytes的rowid,只有在global index中存储的是10bytes的extend rowid,而extend rowid 也是global index出现的一个必要条件,下面我们会解释原因。
为什么golbal index需要把data_object_id#也包含在index rowid entry中呢?如果不包含会这么样?首先我们需要知道index的rowid entry的存在是为了能根据它找到表的这条记录存在哪个具体的物理位置,我们需要知道它在哪个数据文件,在哪个block,在那一行,普通的索引 oracle根据rfile#,block#,row#就可以知道了,但是partition table可以分布在多个表空间,也就是可以分布在多个数据文件,当我们建立local index时,index rowid entry并不包含data_object_id#,因为oracle可以知道这个index 对应的是哪一个table分区,并可以得到table分区的ts#(tablespace号),那么oracle根据ts#和rfile#就可以找到具体的数据文件。
ORACLE数据库字段类型说明类型含义存储描述备注CHAR固定长度字符串最⼤长度2000bytesVARCHAR2可变长度的字符串,最⼤长度4000bytes可做索引的最⼤长度749 NCHAR根据字符集⽽定的固定长度字符串最⼤长度2000bytesNVARCHAR2根据字符集⽽定的可变长度字符串最⼤长度4000bytesDATE⽇期(⽇-⽉-年)DD-MM-YY(HH-MI-SS),经过严格测试,⽆千⾍问题TIMESTAMP⽇期(⽇-⽉-年)DD-MM-YY(HH-MI-SS:FF3),经过严格测试,⽆千⾍问题与DATE相⽐较,TIMESTAMP有⼩数位秒信息LONG超长字符串最⼤长度2G,⾜够存储⼤部头著作RAW固定长度的⼆进制数据最⼤长度2000bytes可存放多媒体图象声⾳等LONG RAW可变长度的⼆进制数据最⼤长度2G可存放多媒体图象声⾳等BLOB⼆进制数据最⼤长度4GCLOB字符数据最⼤长度4GNCLOB根据字符集⽽定的字符数据最⼤长度4GBFILE存放在数据库外的⼆进制数据最⼤长度4GROWID数据表中记录的唯⼀⾏号10bytes**.*.*格式,*为0或1NROWID⼆进制数据表中记录的唯⼀⾏号最⼤长度4000bytesNUMBER(P,S)数字类型P为整数位,S为⼩数位DECIMAL(P,S)数字类型P为整数位,S为⼩数位INTEGER整数类型⼩的整数FLOAT浮点数类型NUMBER(38),双精度REAL实数类型NUMBER(63),精度更⾼**⽬前Oracle数据库⼤概有26个字段类型,⼤体分为六类,分别是字符串类型、数字数据类型、⽇期时间数据类型、=⼤型对象(LOB)数据类型、RAW和LONG RAW数据类型、ROWID和UROWID数据类型。
**当然Oracle还提供⽤户⾃定义的数据类型,但在我这篇不做讨论。
字符串类型Charchar数据类型存储固定长度的字符值。
⼀个CHAR数据类型可以包括1到2000个字符。
一、什么是Oracle RowidOracle中的Rowid是一种用于唯一标识数据库表中行的物理位置区域。
每一行都有一个唯一的Rowid,可以通过该Rowid来直接访问该行,而不需要进行索引查找。
二、Rowid的结构Rowid是Oracle中的一个伪列,它由以下几部分组成:1. 数据对象号(Data Object Number):每个表在数据库中都有一个唯一的数据对象号,它由数据文件号和数据块号组成。
2. 行号(Row Number):每条记录在数据块中的相对位置。
3. 数据文件号(Data File Number):数据库中的每个数据文件都有唯一的编号。
4. 数据块号(Data Block Number):数据文件中的每个数据块都有唯一的编号。
三、Rowid的排序规则Rowid可以作为一种排序规则,可以通过Rowid来对表中的数据进行排序。
在Oracle中,Rowid有三种不同的格式:Extended Rowid、Urowid和Restricted Rowid。
每种格式都有对应的排序规则。
1. Extended Rowid排序规则:Extended Rowid是在大表中使用的Rowid格式,它的排序规则是按照数据对象号、数据块号和行号的顺序进行排序。
这种格式的Rowid可以唯一标识表中的每一条记录。
2. Urowid排序规则:Urowid是在索引中使用的Rowid格式,它的排序规则是按照数据对象号、数据文件号、数据块号和行号的顺序进行排序。
这种格式的Rowid可以唯一标识索引中的每一条记录。
3. Restricted Rowid排序规则:Restricted Rowid是在分区表中使用的Rowid格式,它的排序规则是按照数据对象号、数据文件号、数据块号、行号和分区号的顺序进行排序。
这种格式的Rowid可以唯一标识分区表中的每一条记录。
四、Rowid排序的应用场景Rowid排序可以用于优化查询性能。
Oracle查询表⾥的重复数据⽅法⼀、背景 ⼀张person表,有id和name的两个字段,id是唯⼀的不允许重复,id相同则认为是重复的记录。
⼆、解决 select id from group by id having count(*) > 1 按照id分组并计数,某个id号那⼀组的数量超过1条则认为重复。
如何查询重复的数据select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1PS:将上⾯的>号改为=号就可以查询出没有重复的数据了。
Oracle删除重复数据的SQL(删除所有):删除重复数据的基本结构写法:想要删除这些重复的数据,可以使⽤下⾯语句进⾏删除delete from 表名 a where 字段1,字段2 in(select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)上⾯的SQL注意:语句⾮常简单,就是将查询到的数据删除掉。
不过这种删除执⾏的效率⾮常低,对于⼤数据量来说,可能会将数据库吊死。
建议先将查询到的重复的数据插⼊到⼀个临时表中,然后对进⾏删除,这样,执⾏删除的时候就不⽤再进⾏⼀次查询了。
如下:CREATE TABLE 临时表 AS (select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)上⾯这句话就是建⽴了临时表,并将查询到的数据插⼊其中。
下⾯就可以进⾏这样的删除操作了:delete from 表名 a where 字段1,字段2 in (select 字段1,字段2 from 临时表);Oracle删除重复数据的SQL(留下⼀条记录):oracle中,有个隐藏了⾃动rowid,⾥⾯给每条记录⼀个唯⼀的rowid,我们如果想保留最新的⼀条记录,我们就可以利⽤这个字段,保留重复数据中rowid最⼤的⼀条记录就可以了。
oracle里面的rowid用法Rowid是Oracle数据库中的一个特殊数据类型,用于唯一标识数据库表中的每一行数据。
它可以被用于定位和操作特定的记录,尤其在处理大量数据时很有用。
本文将详细介绍Oracle中的rowid用法。
一、什么是rowid?Rowid是Oracle数据库中的一个伪列,它是一个唯一的标识符,用于唯一地标识数据库表中的每一行。
它由多个部分组成,包括文件号、块号、行号等信息,用于定位和访问存储在数据库中的数据。
二、rowid的结构Rowid由几个关键部分组成,包括数据对象号(data object number, DON)、文件号(file number)、块号(block number)、行号(row number)等。
其格式如下:CC.DDDDD其中,AAAA代表数据对象号,占4个字节;BBBB代表文件号,占4个字节;CCCC代表块号,占4个字节;DDDDD代表行号,占6个字节。
三、rowid的生成方式Oracle数据库会为每个数据块中的记录分配一个唯一的rowid。
rowid的生成方式主要有以下两种:1. 物理行标识符(Physical Row Identifier, Prid):物理行标识符是Oracle数据库生成的默认行标识符,它是唯一的,不可修改,且在记录被删除后,不会再被使用。
2. 逻辑行标识符(Logical Row Identifier, Lrid):逻辑行标识符是Oracle数据库在特定情况下生成的行标识符,例如在使用索引访问表时,数据库会生成逻辑行标识符来提高查询效率。
四、rowid的用法Rowid在Oracle数据库中有着广泛的应用,主要用于以下几个方面:1. 定位数据:通过rowid可以准确定位和访问数据库表中的某一行。
例如,可以使用rowid来快速定位特定的记录,或者将rowid作为查询条件来进行数据检索。
2. 数据修改:rowid也可以用于对数据库表进行数据修改。
Oracle性能优化之oracle中常见的执⾏计划及其简单解释⼀、访问表执⾏计划1、table access full:全表扫描。
它会访问表中的每⼀条记录(读取⾼⽔位线以内的每⼀个数据块)。
2、table access by user rowid:输⼊源rowid来⾃于⽤户指定。
3、table access by index rowid:输⼊源rowid来⾃于索引。
4、table access by global index rowid:全局索引获取rowid,然后再回表。
5、table access by local index rowid:分区索引获取rowid,然后再回表。
6、table access cluster:通过索引簇的键来访问索表。
7、external table access:访问外部表。
8、result cache:结果集可能来⾃于缓存。
9、mat_view rewrite access:物化视图。
⼆、与B-TREE索引相关的执⾏计划1、index unique scan:只返回⼀条rowid的索引扫描,或者unique索引的等值扫描。
2、index range scan:返回多条rowid的索引扫描。
3、index full scan:顺序扫描整个索引。
4、index fast full scan:多块读⽅式扫描整个索引。
5、index skip scan:多应⽤于组合索引中,引导键值为空的情况下索引扫描。
6、and-equal:合并来⾃于⼀个或多个索引的结果集。
7、domain index:应⽤域索引。
三、与BIT-MAP索引相关的执⾏计划1、bitmap conversion:将位转换为rowid或相反。
2、bitmap index:从位图中取⼀个值或⼀个范围。
3、bitmap merge4、bitmap minus:5、bitmap or:四、与表连接相关的执⾏计划1、merge join:排序合并连接。
1. rowid的介绍先对rowid有个感官认识:SQL> select ROWID from Bruce_test where rownum<2;ROWID------------------ ----------AAABnlAAFAAAAAPAAAROWID的格式如下:数据对象编号文件编号块编号行编号OOOOOO FFF BBBBBB RRR 我们可以看出,从上面的rowid可以得知:AAABnl 是数据对象编号AAF是相关文件编号AAAAAP是块编号AAA 是行编号怎么依据这些编号得到具体的十进制的编码值呢,这是经常遇到的问题。
这里需要明白rowid的是基于64位编码的18个字符显示(数据对象编号(6) +文件编号(3) +块编号(6)+ 行编号(3)=18位),其中A-Z <==> 0 - 25 (26)a-z <==> 26 - 51 (26)0-9 <==> 52 - 61 (10)+/ <==> 62 - 63 (2)共64位,明白这个后,就可以计算出10进制的编码值,计算公式如下:d * (b ^ p)其中:b就是基数,这里就是64,p就是从右到左,已0开始的位置数比如:上面的例子文件号AAF,具体的计算应该是:5*(64^0)=5;0*(64^1)=0;0*(64^2)=0;文件号就是0+0+5=5刚才提到的是rowid的显示方式:基于64位编码的18个字符显示,其实rowid的存储方式是:10 个字节即80位存储,其中数据对象编号需要32 位,相关文件编号需要10 位,块编号需要22,位行编号需要16 位,由此,我们可以得出:32bit的object number,每个数据库最多有4G个对象10bit的file number,每个对象最多有1022个文件(2个文件预留)22bit的block number,每个文件最多有4M个BLOCK16bit的row number,每个BLOCK最多有64K个ROWS2. rowid相关的有用的sql最简单的基于rowid的显示方式得到的响应的64位编码对应值的sql:select rowid ,substr(rowid,1,6) "OBJECT",substr(rowid,7,3) "FILE",substr(rowid,10,6) "BLOCK",substr(rowid,16,3) "ROW"from TableName;OWID OBJECT FILE BLOCKROW------------------ ------------ ------ ------------ ------AAABc4AADAAAGLUAAA AAABc4 AAD AAAGLU AAAAAABc4AADAAAGLUAAB AAABc4 AAD AAAGLU AABAAABc4AADAAAGLUAAC AAABc4 AAD AAAGLU AACAAABc4AADAAAGLUAAD AAABc4 AAD AAAGLU AADAAABc4AADAAAGLUAAE AAABc4 AAD AAAGLU AAE 通过dbms_rowid这个包,可以直接的得到具体的rowid包含的信息:select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,dbms_rowid.rowid_block_number(rowid) block_id ,dbms_rowid.rowid_row_number(rowid) num from bruce_t where rownum<5;OBJECT_ID FILE_ID BLOCK_ID NUM---------- ---------- ---------- ----------5944 3 25300 05944 3 25300 15944 3 25300 25944 3 25300 3 一些使用ROWID的函数ROWIDTOCHAR(rowid) :将ROWID转换成STRINGCHARTOROWID('rowid_string') :将STRING转换成ROWID另外,就是自己写的一些函数:(下面的函数是网友eygle提供)create or replace function get_rowid(l_rowid in varchar2)return varchar2isls_my_rowid varchar2(200);rowid_type number;object_number number;relative_fno number;block_number number;row_number number;begindbms_rowid.rowid_info(l_rowid,rowid_type,object_number,relative_fno,block_number, row_number);ls_my_rowid := 'Object# is :'||to_char(object_number)||chr(10)|| 'Relative_fno is :'||to_char(relative_fno)||chr(10)||'Block number is :'||to_char(block_number)||chr(10)||'Row number is :'||to_char(row_number);return ls_my_rowid ;end;/应用上面的函数如下:SQL> select get_rowid(rowid), name from bruce_t;GET_ROWID(ROWID)NAME-------------------------------------------------------------------------------- --------------------------------Object#is :5944BruceLauRelative_fnois :3Block numberis :25300Row numberis :0Object#is :5944MabelTangRelative_fnois :3Block numberis :25300Row number is :1ROWID:ROWID为该表行的唯一标识,是一个伪列,可以用在SELECT中,但不可以用INSERT, UPDATE来修改该值。
注意:ROWID的表指,普通表,cluster table, partition table, subpartition table, index, index partitions and subpartitions(注意:不包含index-organized tables).每个表Oracle都存在一个伪列ROWID,这个伪列可以用SELECT查看,但是不可以用INSERT, UPDATE来修改。
你也不可以用DELETE来删除ROWID列,Oracle使用ROWID列来建立内部索引。
你可以引用ROWID的值,但ROWID并不存放在数据库中,你可以创建一个表包含ROWID数据类型,但Oracle不保证该值是合法的rowids。
用户必须确保该rowid值是真实合法的。
UROWID:UROWID(可以称为通用ROWID,逻辑ROWID): 表的行地址,表指的是index-organized tables。
IOT中物理rowid是可能变化的,另外Oracle要依靠rowid来建立表的索引,所以对IOT表来物理rowid就不行了。
Oracle以表的主键为基础引入UROWID,在物理rowid 基础上建立了第二个索引。
每一个逻辑rowid使用一个第二索引和一个物理推测(IOT中标识块的行)。
UROWID支持逻辑和物理的rowids,列UROWID类型可以存储各种rowids, 从8.1以后的Oracle才有UROWID类型,它也可以用来保存以前的ROWID类型数据信息。
更新IOT的主键可能导致ROWID改变,该行的UROWID也会改变。
Oracle使用rowid数据类型存储行地址,rowid可以分成两种,分别适于不同的对像Physical rowids:存储ordinary table,clustered table,table partition and subpartition,indexe,index partition and subpartitionLogical 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 numberFFF –-表空间相对的数据文件号BBBBBB –-块号RRR ---行号注意不是16进制表示SQL> select rowid,name from obj$ where rownum<=10;ROWID NAME------------------ ------------------------------AAAAASAABAAAAB6ABc ACCESS$AAAAASAABAAAC1QAAK AGGXMLIMPAAAAASAABAAAC1QAAL AGGXQIMPAAAAASAABAAAGiRAAI ALERT_QTAAAAASAABAAAGiRAAh ALERT_QUEAAAAASAABAAAGujAAo ALERT_QUE$1AAAAASAABAAAGujAAp ALERT_QUE$1AAAAASAABAAAGiRAAf ALERT_QUE_NAAAAASAABAAAGiRAAe ALERT_QUE_RAAAAASAABAAAGiRAAG 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 rowidSQL> select dbms_rowid.rowid_to_restricted('AAAAASAABAAAGiRAAG',0) restricted_rowid from dual;RESTRICTED_ROWID------------------00006891.0006.00011.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 rowidSQL> SELECT ROWID,2007-02-01 15:19:282 SUBSTR(ROWID,1,6) "OBJECT",3 SUBSTR(ROWID,7,3) "FIL",4 SUBSTR(ROWID,10,6) "BLOCK",5 SUBSTR(ROWID,16,3) "ROW"6 from obj$ where rownum<=5;ROWID OBJECT FIL BLOCK ROW------------------ ------------ ------ ------------ ------ AAAAASAABAAAAB6AAa AAAAAS AAB AAAAB6 AAa AAAAASAABAAAAB6AAu AAAAAS AAB AAAAB6 AAu AAAAASAABAAAAB6AAF AAAAAS AAB AAAAB6 AAF AAAAASAABAAAAB6AAv AAAAAS AAB AAAAB6 AAv AAAAASAABAAAAB6AAZ AAAAAS AAB AAAAB6 AAZ #restricted rowidSQL> SELECT ROWID,2 SUBSTR(ROWID,15,4) "FILE",3 SUBSTR(ROWID,1,8) "BLOCK",4 SUBSTR(ROWID,10,4) "ROW"5 from obj$ where rownum<=5;ROWID FILE BLOCK RO W------------------ -------- ---------------- --------AAAAASAABAAAAB6AAa 6AAa AAAAASAA AAAA AAAAASAABAAAAB6AAu 6AAu AAAAASAA AAAA AAAAASAABAAAAB6AAF 6AAF AAAAASAA AAAA AAAAASAABAAAAB6AAv 6AAv AAAAASAA AAAA AAAAASAABAAAAB6AAZ 6AAZ AAAAASAA AAAA请注意extented rowid与restricted rowid的编码方式不一样,大家不能拿两种不同编码方式的组件作比较,比如AAAAASAABAAAAB6AAa 这行的File#在两种方式下是有不同的值,表示不同的意义,没有可比性.下面的语句可以查看表的数据分布在几个文件中SQL> SELECT COUNT(DISTINCT(SUBSTR(ROWID,7,3))) "FILES" FROM BOSSSTATSDATA;FILES----------17#下面验证bossstatsdata的数据确实分布在17个文件中SQL> select count(file_name) from dba_data_files where TABLESPACE_NAME= (select TABLESPACE_NAME from user_tables where table_name='BOSSSTATSDATA');COUNT(FILE_NAME)----------------17总结Rowid的使用场景1) 构建索引结构, 每个key都有一个rowid指向相应的表行2) rowid是访问表行的最快的方法3) rowid可用于观察表数据是怎样组织的4) rowid是表行的唯一标识符在任何DML中使用rowid时,应该注意确保相关的行不会改变物理地址(不会被export/import,delete)1.3 logical rowids用于表达IOT行地址的Logical rowid存储在索引的叶子节点中,会随着索引entry 的insert在块内或块间移动,所以,它不是基于物理地址而是基于primary key的标识符,所以取名叫logcial rowidOracle使用logical rowids来构建IOT的secondary indexes由于在实际的应用中很少会使用到IOT这种对像,关于logical rowid更详细的描述可以参见<<concepts>>中相关章节Part IV Oracle Database Application Development26 Native DatatypesOverview of ROWID and UROWID Datatypes1.4 非oracle table中的rowid在非oracle系统中,不同的系统有不同的rowid格式,并且,不能使用前述标准的rowid 到varchar2/16进制的转换方法, 所以,在这种情况下,应用程序可以使用rowid数据类型,不过要使用非标准的转换方法 (最长256bytes的16进制)非oracle 系统中的rowid也能存储在UROWID数据类型中。