首页 > 试题

rowed

更新时间:2022-11-14 00:49:22 阅读: 评论:0

平几纲目适合几年级-实对称矩阵


2022年11月14日发(作者:哪种专业就业前景好)

【转载】oracle之rowid详解

本⽂讨论的是关于oracle从8i开始引进object的概念后的rowid,即扩展(extended)的rowid:

的介绍

先对rowid有个感官认识:

SQL>

lectROWIDfromBruce_testwhererownum<2;

ROWID----------------------------AAABnlAAFAAAAAPAAAROWID的格式如下:

数据对象编号⽂件编号块编号⾏编号OOOOOOFFFBBBBBBRRR

我们可以看出,从上⾯的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的objectnumber,每个最

多有4G个对象10bit的filenumber,每个对象最多有1022个⽂件(2个⽂件预留)22bit的blocknumber,每个⽂件最多有4M个BLOCK16bit的rownumber,每个BLOCK最多有

64K个ROWS

相关的有⽤的sql

最简单的基于rowid的显⽰⽅式得到的响应的64位编码对应值的sql:

lectrowid,substr(rowid,1,6)"OBJECT",substr(rowid,7,3)"FILE",substr(rowid,10,6)"BLOCK",substr(rowid,16,3)"ROW"fromTableName;

OWIDOBJECTFILEBLOCKROW------------------------------------------------------AAABc4AADAAAGLUAAAAAABc4AADAAAGLUAAA

AAABc4AADAAAGLUAABAAABc4AADAAAGLUAABAAABc4AADAAAGLUAACAAABc4AADAAAGLUAACAAABc4AADAAAGLUAADAAABc4

AADAAAGLUAADAAABc4AADAAAGLUAAEAAABc4AADAAAGLUAAE

通过dbms_rowid这个包,可以直接的得到具体的rowid包含的信息:

lectdbms__object(rowid)object_id,dbms__relative_fno(rowid)file_id,dbms__block_number(rowid)block_id,dbms__row_number(rowid)numfrombruce_twhererownum<5;

OBJECT_IDFILE_IDBLOCK_IDNUM----------------------------------------594432532

59443253003

⼀些使⽤ROWID的函数ROWIDTOCHAR(rowid):将ROWID转换成STRINGCHARTOROWID('rowid_string'):将STRING转换成ROWID

另外,就是⾃⼰写的⼀些函数:(下⾯的函数是⽹友eygle提供)

createorreplacefunctionget_rowid

(l_rowidinvarchar2)returnvarchar2isls_my_rowidvarchar2(200);rowid_typenumber;object_numbernumber;relative_fnonumber;block_numbernumber;row_numbernumber;

begindbms__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_fnois:'||to_char(relative_fno)||chr(10)||

应⽤上⾯的函数如下:SQL>

lectget_rowid(rowid),namefrombruce_t;

GET_ROWID(ROWID)NAME

----------------------------------------------------------------------------------------------------------------Object#is:5944BruceLauRelative_fnois

:3Blocknumberis:25300Rownumberis:0Object#is

:5944MabelTangRelative_fnois:3Blocknumberis:25300Rownumberis

:1

ROWID:ROWID为该表⾏的唯⼀标识,是⼀个伪列,可以⽤在SELECT中,但不可以⽤INSERT,UPDATE来修改该值。注意:ROWID的表指,普通表,clustertable,

partitiontable,subpartitiontable,index,indexpartitionsandsubpartitions(注意:不包含index-organizedtables).每个表Oracle都存在⼀个伪列ROWID,这个伪列可以⽤

SELECT查看,但是不可以⽤INSERT,UPDATE来修改。你也不可以⽤DELETE来删除ROWID列,Oracle使⽤ROWID列来建⽴内部索引。你可以引⽤ROWID的值,但ROWID

并不存放在数据库中,你可以创建⼀个表包含ROWID数据类型,但Oracle不保证该值是合法的rowids。⽤户必须确保该rowid值是真实合法的。UROWID:UROWID(可以称为

通⽤ROWID,逻辑ROWID):表的⾏地址,表指的是index-organizedtables。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可以分成两种,分别适于不同的对像

Physicalrowids:存储ordinarytable,clusteredtable,tablepartitionandsubpartition,indexe,indexpartitionandsubpartition

Logicalrowids:存储IOT的⾏地址

另⼀种rowid类型叫universalrowed(UROWID),⽀持上述physicalrowid和logicalrowed,并且⽀持⾮oracletable,即⽀持所有类型的rowid,但COMPATIBLE必须在8.1或以上.

1.1ROWID伪列

每个表在oracle内部都有⼀个ROWID伪列,它在所有sql中⽆法显⽰,不占存储空间;它⽤于从表中查询⾏的地址或者在where中进⾏参照,⼀个例⼦如下:

SELECTROWID,last_nameFROMemployees;

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

再次强调⼀次,rowid伪列不存储在数据库中,它不是数据库数据,这是从databa及table的逻辑结构来说的,事实上,在物理结构上,每⾏由⼀个或多个rowpieces组成,每个row

piece的头部包含了这个piece的address,即rowid.从这个意义上来说,rowid还是占了磁盘空间的.

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

1.2,physicalrowids

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

这⾥要注意⼀点,对于clusteredtable来说,根据它的存储特点,在同⼀个block中的不同table的⾏可能具有同⼀个rowid;⽽nonclusteredtable,每⼀⾏或初始⾏⽚(initialrowpiece)都有

唯⼀的rowid

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

Physicalrowid可以是下⾯任⼀⼀种格式:

1)Extendedrowid

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

2)Restrictedrowid

使⽤数据库范围的数据址地址,oracle7或更早前的版本使⽤

1.2.1extenedrowid

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

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

OOOOOO-–dataobjectnumber

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

BBBBBB–-块号

RRR---⾏号

注意不是16进制表⽰

SQL>

lectrowid,namefromobj$whererownum<=10;

ROWIDNAME

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

AAAAASAABAAAAB6ABcACCESS$

AAAAASAABAAAC1QAAKAGGXMLIMP

AAAAASAABAAAC1QAALAGGXQIMP

AAAAASAABAAAGiRAAIALERT_QT

AAAAASAABAAAGiRAAhALERT_QUE

AAAAASAABAAAGujAAoALERT_QUE$1

AAAAASAABAAAGujAApALERT_QUE$1

AAAAASAABAAAGiRAAfALERT_QUE_N

AAAAASAABAAAGiRAAeALERT_QUE_R

AAAAASAABAAAGiRAAGALERT_TYPE

我们可以使⽤dbms_rowid从extenedrowid中抽取各部分信息,或者将extenedrowid转换成restrictedrowed,详细的信息参见_rowid的规范

#根据rowid抽块对像编号

SQL>

lectdbms__object('AAAAASAABAAAGiRAAG')obj#fromdual;

OBJ

#----------

18

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

SQL>

lectdbms__relative_fno('AAAAASAABAAAGiRAAG')rfile#fromdual;

RFILE

#----------

1

#根据rowid抽取块号

SQL>

lectdbms__BLOCK_NUMBER('AAAAASAABAAAGiRAAG')block#fromdual;

BLOCK

#----------

26769

#根据rowid抽取⾏号

SQL>

lectdbms__row_number('AAAAASAABAAAGiRAAG')row#fromdual;

ROW

#----------

6

#将extendedrowid转换成为restrictedrowid

SQL>

lectdbms__to_restricted('AAAAASAABAAAGiRAAG',0)restricted_rowidfromdual;

RESTRICTED_ROWID

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

00006891.0006.0001

1.2.2restrictedrowid

限制地址⾏号与扩展地址⾏号编码⽅式不⼀样,它在内部使⽤⼆进制⽅式表⽰,当⽤lect查询时,会转换成varchar2/16进制的混合形式,它的组织⽅式如下:

(block#.row#.file#)

注意,这⾥的⽂件号是绝对⽂件号,⽽extendedrowid中是相对⽂件号(相对表空间)

Restrictedrowid中不再有objectnumber,因为从绝对⽂件号可以唯⼀确定数据块

样例可以参考前⾯的00006891.0006.0001

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

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

#extendedrowid

SQL>

SELECTROWID,SUBSTR(ROWID,1,6)"OBJECT",SUBSTR(ROWID,7,3)"FIL",SUBSTR(ROWID,10,6)"BLOCK",SUBSTR(ROWID,16,3)"ROW"fromobj$whererownum<=5;

ROWIDOBJECTFILBLOCKROW------------------------------------------------------AAAAASAABAAAAB6AAaAAAAASAABAAAAB6AAa

AAAAASAABAAAAB6AAuAAAAASAABAAAAB6AAuAAAAASAABAAAAB6AAFAAAAASAABAAAAB6AAFAAAAASAABAAAAB6AAvAAAAAS

AABAAAAB6AAvAAAAASAABAAAAB6AAZAAAAASAABAAAAB6AAZ

#restrictedrowidSQL>

SELECTROWID,SUBSTR(ROWID,15,4)"FILE",SUBSTR(ROWID,1,8)"BLOCK",SUBSTR(ROWID,10,4)"ROW"fromobj$whererownum<=5;

ROWIDFILEBLOCKROW--------------------------------------------------AAAAASAABAAAAB6AAa6AAaAAAAASAAAAAAAAAAASAABAAAAB6AAu

6AAuAAAAASAAAAAAAAAAASAABAAAAB6AAF6AAFAAAAASAAAAAAAAAAASAABAAAAB6AAv6AAvAAAAASAAAAAA

AAAAASAABAAAAB6AAZ6AAZAAAAASAAAAAA

请注意extentedrowid与restrictedrowid的编码⽅式不⼀样,⼤家不能拿两种不同编码⽅式的作⽐较,⽐如AAAAASAABAAAAB6AAa这⾏的File#在两种⽅式下是有不同的值,表

⽰不同的意义,没有可⽐性.

下⾯的语句可以查看表的数据分布在⼏个⽂件中

SQL>

SELECTCOUNT(DISTINCT(SUBSTR(ROWID,7,3)))"FILES"FROMBOSSSTATSDATA;

FILES----------17

#下⾯验证bossstatsdata的数据确实分布在17个⽂件中

SQL>

lectcount(file_name)fromdba_data_fileswhereTABLESPACE_NAME=(lectTABLESPACE_NAMEfromur_tableswheretable_name='BOSSSTATSDATA');

COUNT(FILE_NAME)----------------17

总结Rowid的使⽤场景

1)构建索引结构,每个key都有⼀个rowid指向相应的表⾏

2)rowid是访问表⾏的最快的⽅法

3)rowid可⽤于观察表数据是怎样组织的

4)rowid是表⾏的唯⼀标识符

在任何DML中使⽤rowid时,应该注意确保相关的⾏不会改变物理地址(不会被export/import,delete)

1.3logicalrowids⽤于表达IOT⾏地址的Logicalrowid存储在索引的叶⼦节点中,会随着索引entry的inrt在块内或块间移动,所以,它不是基于物理地址⽽是基于primarykey的

标识符,所以取名叫logcialrowid使⽤logicalrowids来构建IOT的condaryindexes由于在实际的应⽤中很少会使⽤到IOT这种对像,关于logicalrowid更详细的描述可以参见

<>中相关章节PartIVOracleDatabaApplicationDevelopment26NativeDatatypesOverviewofROWIDandUROWIDDatatypes

1.4⾮oracletable中的rowid在⾮oracle中,不同的系统有不同的rowid格式,并且,不能使⽤前述标准的rowid到varchar2/16进制的转换⽅法,所以,在这种情况下,应⽤程序可以使

⽤rowid数据类型,不过要使⽤⾮标准的转换⽅法(最长256bytes的16进制)⾮oracle系统中的rowid也能存储在UROWID数据类型中

作者“jukyoc”

本文发布于:2022-11-14 00:49:22,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/88/14399.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:happy的过去式
下一篇:庄重的乞讨
标签:rowed
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图