本篇文章给大家带来了关于oracle的相关知识,其中主要介绍了关于rowid的相关问题,oracle数据库的表中的每一行数据都有一个唯一的标识符,或者称为rowid,在oracle内部通常就是使用它来访问数据的,希望对大家有帮助。
推荐教程:《oracle学习教程》
一、rowid中保存信息概述oracle数据库的表中的每一行数据都有一个唯一的标识符,或者称为rowid,在oracle内部通常就是使用它来访问数据的。rowid需要 10个字节的存储空间,并用18个字符来显示。该值表明了该行在oracle数据库中的物理具体位置。可以在一个查询中使用rowid来表明查询结果中包含该值。
保存rowid需要10个字节或者是80个位二进制位。一个扩展rowid采用10个byte来存储,共80bit,其中obj#32bit,rfile#10bit,block#22bit,row#16bit。所以相对文件号不能超过1023,也就是一个表空间的数据文件不能超过1023个(不存在文件号为0的文件),一个datafile只能有2^22=4m个block,,一个block中不能超过2^16=64k行数据。而一个数据库内不能有超过2^32=4g个object。
这80个二进制位分别是:
1. 数据对象编号,表明此行所属的数据库对象的编号,每个数据对象在数据库建立的时候都被唯一分配一个编号,并且此编号唯一。数据对象编号占用大约32位。
2. 对应文件编号,表明该行所在文件的编号,表空间的每一个文件标号都是唯一的。文件编号所占用的位置是10位。
3. 块编号,表明改行所在文件的块的位置块编号需要22位。
4. 行编号,表明该行在行目录中的具体位置行编号需要16位。
这样加起来就是80位。
备注:在oracle 8版本以前,rowid由file# block# row#组成,占用6个bytes的空间,10 bit 的 file# ,22bit 的 block# ,16 bit 的 row#。oracle8及之后版本改为10个bytes的空间。
oracle的物理扩展rowid有18位,每位采用64位编码,分别用a~z、a~z、0~9、+、/共64个字符表示。a表示0,b表示1,……z表示25,a表示26,……z表示51,0表示52,……,9表示61,+表示62,/表示63。
select t.rowid, t.* from dept t
为了验证rowid的存储空间为10字节,其中32bit的object#,10bit的rfile#,22bit的block#,16bit的row#。我们需要使用dump函数。
select rowid,dump(rowid,16) from dept
二、验证查看rowid内容1、使用dbms_rowid包中函数查看
select rowid, dbms_rowid.rowid_object(rowid) as object, dbms_rowid.rowid_relative_fno(rowid) as filenum, dbms_rowid.rowid_block_number(rowid) as block, dbms_rowid.rowid_row_number(rowid) as rown from dept;
结果如下:
2、从表中查询数据信息
1)查询对象编号:data_object_id
select object_name, object_type, subobject_name, object_id, data_object_id from dba_objects t where t.object_name ='dept' and t.owner = 'chf';
结果如下:
说明:data_object_id与object_id的区别
object_id和data_object_id 都是对象的唯一标识。
object_id是对象的逻辑标识
data_object_id是对象的物理标识
只有表,索引,undo这些有实际物理存储位置的对象才有data_object_id。而对于没有物理存储的对象,data_object_id就是空。例如:(procedure,function,package,data type,db link,mv定义,view定义,临时表,分区表定义等等)
大多数情况下两者是相等的。但对object 进行truncate,move, rebuild 等操作后,data_object_id就会发生改变,而object_id不会改变。
对标dept执行truncate操作,代码:truncate table dept;
再次查询结果:
将truncate前数据重新插入表中,查看rowid代表对象号的部分已发生变化由aaauoo变为aaauop,增加了1。
2)查询文件编号:
select t.segment_name, t.header_block, t.blocks, t.extents, t.relative_fno from dba_segments t where t.segment_name = 'dept' and t.owner = 'chf';
header_block:本表的第一个数据块号
blocks:本表的数据块数
relative_fno:相对文件编号
结果如下:
说明:
从oracle8开始,oracle开始使用“相对文件号”,使原来一个数据库最多只能有1023个文件,扩展为一个表空间最多可以有1023个文件,每个库最多可以有65534个文件
验证文件号
select t.table_name, t.tablespace_name, g.file_name, g.file_id, g.relative_fno from dba_tables t inner join dba_data_files g on g.tablespace_name = t.tablespace_name where t.table_name = 'dept' and t.owner = 'chf';
执行结果:
因为创建用户时没用指定默认表空间,建表时也没用指定表空间,所以此处使用的users表空间(大家不必在意这些细节...),可以看到文件号和相对文件号都是 4 ,这是因为我的数据库中每个表空间只有一个数据文件,如果一个表空间有多个数据文件,这两个值有可能不一样。
知识扩展:
我们可以使用跟踪文件查看数据文件信息,命令:alter session set events 'immediate trace name file_hdrs level 10';
执行完此代码后,将在数据库服务器生成一个跟踪文件,查看文件路径代码:
selectu_dump.value || '/' ||db_name.value || '_ora_' ||v$process.spid ||nvl2(v$process.traceid, '_' || v$process.traceid, null )|| '.trc' trace filefromv$parameter u_dumpcross join v$parameter db_namecross join v$processjoin v$sessionon v$process.addr = v$session.paddrwhereu_dump.name = 'user_dump_dest' anddb_name.name = 'db_name' andv$session.audsid=sys_context('userenv','sessionid');
推荐教程:《oracle教程》
以上就是oracle学习指南之rowid详解的详细内容。