Chinaunix首页 | 论坛 | 博客
  • 博客访问: 343198
  • 博文数量: 115
  • 博客积分: 1019
  • 博客等级: 准尉
  • 技术积分: 1104
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-22 15:02
个人简介

别想万里,要把一只脚放到另一脚的前边

文章分类

全部博文(115)

文章存档

2018年(1)

2015年(2)

2014年(31)

2013年(38)

2012年(43)

我的朋友

分类: LINUX

2014-03-16 13:04:06

本文来自互联网 ,如有侵权请告诉本人


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数据块深入分析总结


阅读(798) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~