暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

解析ORACLE ROWID

解析ORACLE ROWID
通过rowid查询block,通过block查询rowid

-- 查询rowid 所在数据块 数据行 set line 190 pages 900 col location for a20 col rowid_chr for a30 select rowid,id,dbms_rowid.rowid_object(rowid)||','||dbms_rowid.rowid_relative_fno(rowid)||','|| dbms_rowid.rowid_block_number(rowid)||','||dbms_rowid.rowid_row_number(rowid) location ,sys.rowid_chr(rowid) rowid_chr from cog.t2; -- 查看数据块的rowid select dbms_rowid.rowid_create(1,101114,6,139,0) rowid_chr from dual; -- 测试过程 -- 建表 drop table cog.t2 purge; create table cog.t2(id int,name varchar2(4000),msg clob) tablespace GZ2; create unique index cog.ind_t2_u on cog.t2(id); insert into cog.t2 select rownum,lpad('A',4000,'X'),to_clob(dbms_random.string('x', 4000))||dbms_random.string('x', 4000) from dual connect by rownum<=10 order by 1; define owner=COG; define tb_name=T2; -- 查询数据DATA_OBJECT_ID select DATA_OBJECT_ID from dba_objects where owner='&&owner' and OBJECT_NAME='&&tb_name'; DATA_OBJECT_ID -------------- 101114 -- 查询数据分布 dba_extents select * from dba_extents where owner='&&owner' and segment_name='&&tb_name'; OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO ------ ------------ --------------- ------------ ---------- ---------- ---------- ---------- ---------- ------ ------------ COG T2 TABLE GZ2 0 26 136 65536 8 26 COG T2 TABLE GZ2 1 26 168 65536 8 26 -- 注意:前面3个块作为数据文件头,第4个块开始存放数据 -- 函数从数据块反向生成rowid dbms_rowid.rowid_create(type,object_number,relative_fno,block_number,row_number) select dbms_rowid.rowid_create(1,101114,6,136+3,0) rowid_chr from dual; ROWID_CHR ------------------------------ AAAYr6AAGAAAACLAAA -- 查询rowid 所在数据块 数据行 set line 190 pages 900 col location for a20 col rowid_chr for a30 select rowid,id,dbms_rowid.rowid_object(rowid)||','||dbms_rowid.rowid_relative_fno(rowid)||','|| dbms_rowid.rowid_block_number(rowid)||','||dbms_rowid.rowid_row_number(rowid) location ,sys.rowid_chr(rowid) rowid_chr from cog.t2; ROWID ID LOCATION ------------------ ---------- -------- AAAYr6AAaAAAACLAAA 4 26,139,0 AAAYr6AAaAAAACMAAA 5 26,140,0 AAAYr6AAaAAAACNAAA 1 26,141,0 AAAYr6AAaAAAACOAAA 2 26,142,0 AAAYr6AAaAAAACPAAA 3 26,143,0 AAAYr6AAaAAAACoAAA 7 26,168,0 AAAYr6AAaAAAACpAAA 8 26,169,0 AAAYr6AAaAAAACrAAA 9 26,171,0 AAAYr6AAaAAAACsAAA 10 26,172,0 AAAYr6AAaAAAACvAAA 6 26,175,0 -- 可以看到,数据存储并不是按照序号顺序存储的, -- 但是rowid一定是和块的顺序从小往大排序 -- 测试数据删除插入新的数据 delete from cog.t2 where id in(4,5,1,3,2,7,8); commit; alter system checkpoint; alter system flush shared_pool; alter system flush BUFFER_CACHE; -- 再插入2行新的数据 insert into cog.t2 select rownum+50,lpad('A',4000,'X'),to_clob(dbms_random.string('x', 4000))||dbms_random.string('x', 4000) from dual connect by rownum<=2 order by 1; ROWID ID LOCATION ------------------ ---------- -------------------- AAAYr6AAaAAAACLAAA 52 26,139,0 AAAYr6AAaAAAACqAAA 101 26,170,0 AAAYr6AAaAAAACrAAA 9 26,171,0 AAAYr6AAaAAAACsAAA 10 26,172,0 AAAYr6AAaAAAACtAAA 102 26,173,0 AAAYr6AAaAAAACuAAA 51 26,174,0 AAAYr6AAaAAAACvAAA 6 26,175,0 -- 可以看到,重新插入的数据,使用的ROWID是原来那个块的那个ROWID,ROW不会随主键增加而增加,只会根据当前行(数据存放的块)所在的位置定位, -- 可以为ROWID数据分片提供理论依据 -- ROWID为64进制 后3位表示行号 行号理论最大值:262143 实际最大值为65535 ROWID 一共18位 64进制计数A-Za-z0-9(+/) AAAYr6AAaAAAACLAAA AAAYr6 01-06位 data_objectid AAa 07-09位 data_fileid AAAACL 10-15位 blockid AAA 16-18位 rownum -- 可以用以下SQL来验证rowid计数的64位进制 select rownum -1 rm,dbms_rowid.rowid_create(1,101114,26,139,0+rownum-1) from dual connect by rownum<=65; -- 分解rowid define rowid_chr='AAAYr6AAaAAAACLAAA'; select substr('&rowid_chr',1,6) obj_id,substr('&rowid_chr',7,3) file_id,substr('&rowid_chr',10,6) block_id,substr('&rowid_chr',16,3) rown from dual; -- 查询分解的rowid对应的值 select rowid_tonumber(substr('&rowid_chr',1,6)) obj_id,rowid_tonumber(substr('&rowid_chr',7,3)) file_id ,rowid_tonumber(substr('&rowid_chr',10,6)) block_id,rowid_tonumber(substr('&rowid_chr',16,3)) rown from dual; select sys.rowid_tonumber('AAAYr6') from dual; -- 以下函数可以从ROWID中识别出相应的数值 create or replace function sys.rowid_tonumber(rowid_chr in varchar2) return number as v_number NUMBER := 0; begin with t0 as ( select rownum-1 id from dual connect by rownum<=64 ),t as( select id,case when id<26 then chr(id+65) when id<52 then chr(id+97-26) when id<62 then chr(id+48-52) when id=62 then '+' when id=63 then '/' else '' end chr from t0 ),p0 as( select lpad(rowid_chr,6,'A') chr from dual ),p as( select abs(6-id) id,substr(chr,id,1) chr from p0,(select rownum id from dual connect by rownum<=6) ),s as( select t.id,t.chr,p.id,p.chr,t.id*power(64,p.id) loc from t join p on t.chr=p.chr ) select sum(loc) into v_number from s; return v_number; end rowid_tonumber; / select rowid_tonumber('AAa') rowid_tonumber from dual; create or replace function rowid_chr(rowid_ch in varchar2) return varchar2 as v_objid NUMBER := 0; v_fileid NUMBER := 0; v_blockid NUMBER := 0; v_rownum NUMBER := 0; begin select sys.rowid_tonumber(substr(rowid_ch,1,6)) ,sys.rowid_tonumber(substr(rowid_ch,7,3)) ,sys.rowid_tonumber(substr(rowid_ch,10,6)) ,sys.rowid_tonumber(substr(rowid_ch,16,3)) into v_objid,v_fileid,v_blockid,v_rownum from dual; return v_objid||','||v_fileid||','||v_blockid||','||v_rownum; end rowid_chr; / grant execute on rowid_chr to public; col rowid_chr for a30 select rowid_chr('AAAYr6AAaAAAACLAAA') rowid_chr from dual; ROWID_CHR ------------------------------ 101114,26,139,0
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论