rowid的是怎么组成的

rowid就像是记录的详细地址,想要寻找记录就需要通过这个详细地址去寻找。
rowid存储在索引中而不是在表中。
我们可以通过以下包通过rowid找到文件号,块号,行号。
dbms_rowid.rowid_relative_fno    -- 文件号
dbms_rowid.rowid_block_number  --块号
dbms_rowid.rowid_row_number   --行号

liu.test表插入了一行测试数据,我们先找到该行记录的rowid,fno(relative file id),bno(block id)
rowid由对象号,数据文件号,块号,行号构成。
然后我们通过base64表将rowid分解转化成十进制
1-6位,对象号:AAAR3s-->0 0 0 1755 44 -->0*64^5+0*64^4+0*64^3+17*64^2+55*64^1+44*64^0=73196 
7-9位,数据文件号:AAM-->0 0 12 -->0*64^2+0*64^1+12*64^0=12 (对应fno)
10-15位,块号:AAAACG-->00 0 2 6-->0*64^5+0*64^4+0*64^3+0*64^2+2*64^1+6*64^0=134 (对应bno)
16-18位,行号:AAA--> 0 0 0--> ...=0

 
base64转换表:


现在数据文件号,块号都对应了,我们来查找对象号

 

 

SQL> select owner,object_name,object_id from dba_objects where object_name = 'TEST';
OWNER           OBJECT_NAME                           OBJECT_ID
---------- ------------------------------ ----------
LIU           TEST                                73196


对象号也对应了
 
行号为0,是否每一行+1,从0开始呢。我们再插入数据进行验证
循环插入50w行数据

 

begin
for i in 1..500000
loop
insert into liu.test values(i);
end loop;
commit;
end;
/
SQL> select count(1) from liu.test;
  COUNT(1)
----------
    500001
SQL> select * from (select rowid from liu.test order by  a asc) where rownum<=5;
ROWID
------------------
AAAR3sAAMAAAACGAAA
AAAR3sAAMAAAACGAAB
AAAR3sAAMAAAACGAAC
AAAR3sAAMAAAACGAAD
AAAR3sAAMAAAACGAAE


可以看出,当行号是持续递增的,0表示第一行,1表示第二行以此类推
但是这里会有一个问题,行号有最大值--///,也就是说每个块只能存储AAA--///的数据,也就是0--63*64^2+63*64^1+63*64^0,也就是64^3=262144行。
但是oracle并没有使用所有的basic64编码号

 

select a,rowid from liu.test where rowid like 'AAAR3sAAMAAAACG___' order by rowid asc;
...
         A ROWID
---------- ------------------
       649 AAAR3sAAMAAAACGAKJ
       650 AAAR3sAAMAAAACGAKK
       651 AAAR3sAAMAAAACGAKL
       652 AAAR3sAAMAAAACGAKM
       653 AAAR3sAAMAAAACGAKN
       654 AAAR3sAAMAAAACGAKO
       655 AAAR3sAAMAAAACGAKP
       656 AAAR3sAAMAAAACGAKQ
       657 AAAR3sAAMAAAACGAKR
       658 AAAR3sAAMAAAACGAKS
       659 AAAR3sAAMAAAACGAKT
 
660 rows selected.
 
 
select a,rowid from liu.test where rowid like 'AAAR3sAAMAAAACH___' order by rowid asc;
...
         A ROWID
---------- ------------------
      1309 AAAR3sAAMAAAACHAKJ
      1310 AAAR3sAAMAAAACHAKK
      1311 AAAR3sAAMAAAACHAKL
      1312 AAAR3sAAMAAAACHAKM
      1313 AAAR3sAAMAAAACHAKN
      1314 AAAR3sAAMAAAACHAKO
      1315 AAAR3sAAMAAAACHAKP
      1316 AAAR3sAAMAAAACHAKQ
      1317 AAAR3sAAMAAAACHAKR
      1318 AAAR3sAAMAAAACHAKS
      1319 AAAR3sAAMAAAACHAKT
 
660 rows selected.


事实并非我们想象的那样,每个块最多存放660行数据。这也是有道理的,因为oracle块的大小是固定的,比如8k,那么他的行数不可能非常的高。
那么再看看660行发生了什么

 

SQL> select t1.rid from  (select rowid rid,rownum rn from liu.test order by  a asc)t1 where t1.rn>=658 and t1.rn<=662;
RID
------------------
AAAR3sAAMAAAACDAKR
AAAR3sAAMAAAACDAKS
AAAR3sAAMAAAACDAKT
AAAR3sAAMAAAACEAAA
AAAR3sAAMAAAACEAAB
当行到AKT时,块号+1,行号从0开始计算。
 
总结:
1.rowid记录了行记录的物理存放位置,通过basic64编码或者dbms_rowid转换转换rowid找到那个位置
2.每个块最多存放660行记录,当插入数据时要超过阈值(pct_free)的时候便把数据插入到下一个块
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值