本文来自互联网 ,如有侵权请告诉本人
Orale ---- rowid [根据老谢视频整理]
rowid: 顾名思义就是一个行的唯一id号,用rowid可以直接定位到数据块上从而实现快速找到块(索引)
eg.
ROWID ID
------------------ ----------
AAANnSAAEAAAAGIAAA 10
那么这么一串长的数字表示什么呢?
AAANnS(6) ---- SELECT t.data_object_id FROM dba_objects t data_object_id :对象的物理唯一标示符
AAE(3) ---- SELECT t.relative_fno FROM dba_data_files t relative_fno: 在一个表空间中唯一标示一个数据文件的id号
AAAAGI(6)---- 块编号
AAA(3)---- 行编号
那么如何 用这四组数字来定位这个行呢?
1. 首先要明白rowid的编码规则
[A-Z] ---------- 0-25
[a-z] ---------- 26-51
[0-9] ---------- 52-61
+ ---------- 62
/ ---------- 63
所以 6+3+6+3=18 位 上都有64 中可能,就形成了64 位编码。
2.上边rowid 找出它的各个标示号:
data_object_id :
SELECT 0*POWER(64,5)+0*POWER(64,4)+0*POWER(64,3)+13*POWER(64,2)+39*POWER(64,1)+18*POWER(64,0) FROM dual == 55762
SELECT t.data_object_id FROM dba_objects t WHERE t.object_name='A' ==55762
relative_fno: 4 dba_data_files 找到这个表空间的数据文件 数据文件 note: 这里找到表空间,表空间的数据文件
block_id:
SELECT 6*POWER(64,1)+ 8*POWER(64,0) FROM dual == 392
SELECT * FROM dba_extents t WHERE t.segment_name='A'
信息: extend_id 0 file#4 block_id:385 blocks:8 385 --392 刚好确认:在这个extend 的最后一个block 上
row id: 一个block 可能包含很多行,这个显示在这个block 的第一行上
3. 通过编码得到的启示:
其实rowid的存储方式是:10 个字节即80位存储,其中数据对象编号需要32 位,相关文件编号需要10 位,块编号需要22,位行编号需要16
位,[为什么要这要这样存储我也不清楚,知道的邮件我哦,:)]由此,我们可以得出:
32bit的object number,每个数据库最多有4G个对象
10bit的file number,每个对象最多有1022个文件(2个文件预留)
22bit的block number,每个文件最多有4M个BLOCK
16bit的row number,每个BLOCK最多有64K个ROWS
4. 如何简单得出或者oracle 是如何根据rowid快速定位block ?
通过dbms_rowid这个包,可以直接的得到具体的rowid包含的信息:
SELECT ROWID,a.*,dbms_rowid.rowid_object(ROWID),dbms_rowid.rowid_relative_fno(ROWID),dbms_rowid.rowid_block_number
(ROWID),dbms_rowid.rowid_row_number(ROWID) from a;
网友提供:
create or replace function get_rowid
(l_rowid in varchar2)
return varchar2
is
ls_my_rowid varchar2(200);
rowid_type number;
object_number number;
relative_fno number;
block_number number;
row_number number;
begin
dbms_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;
/
SELECT get_rowid('AAANnSAAEAAAAGIAAA') FROM dual ;
Object# is :55762
Relative_fno is :4
Block number is :392
Row number is :0
5. dump 出来反编译对比我们此文中提到的 rowid,看看它在oracle 中到底有什么用
请参见这篇文章:http://czmmiao.iteye.com/blog/1495332 Oracle数据块深入分析总结