楼主: yangtingkun

[精华] Oracle基本数据类型存储格式浅析

[复制链接]
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34ITPUB元老
日期:2006-09-11 15:36:37
21#
发表于 2005-3-19 18:07 | 只看该作者

Re: Oracle基本数据类型存储格式浅析(四)——ROWID类型(一)

最初由 yangtingkun 发布
[B]

SQL> select row_id, dump(row_id, 16) dump_rowid from test_rowid;


ROW_ID             DUMP_ROWID
------------------ -------------------------------------------------
AAABnRAAGAAAACWAAA Typ=69 Len=10: 0,0,19,d1,1,80,0,96,0,0


前4位表示ROWID的前6位,也就是DATA_OBJECT_ID信息。数据以数值的格式保存。

后面4位比较特殊,是数据文件号和BLOCK数的“和”值构成。

数据文件的数值乘64后保存在5、6位上。

SQL> select to_number('0180', 'xxxx') from dual;

TO_NUMBER('0180','XXXX')
------------------------
                     384

SQL> select 6*64 from dual;


        6*64
------------
         384

同时,6位BLOCK的值,也保存在这4位上,并与数据文件转存结果相加。仍然是以数字格式存放。


SQL> select to_number('96', 'xxx') from dual;


TO_NUMBER('96','XXX')
---------------------
                  150


SQL> select 2*64 + 22 from dual;


   2*64+22
----------
       150


由于采用两位保存数据文件的值,且最小单位是64,因此,ROWID中可以保存的数据文件数是1024,超过1024会造成ROWID的重复。


SQL> select 256*256/64 from dual;


256*256/64
----------
      1024


由于BLOCK的值和数据文件共用这4位,因此BLOCK的第3位最大值应小于64,这样才能保证ROWID的不重复。因此BLOCK值的最大值应该是4194304。


SQL> select 64*256*256 from dual;


64*256*256
----------
   4194304


最后两位保存BLOCK中记录的值。这个值的最大值是65536。


SQL> select 256*256 from dual;


   256*256
----------
     65536


出自:http://blog.itpub.net/post/468/11046 [/B]

想請教一下﹕
您 上面所說的﹕
"后面4位比较特殊,是数据文件号和BLOCK数的“和”值构成。"
是什么意思﹖我不是能理解這個 "和" 怎么理解。 在我看來
file id 與 block id 分別是在存儲在 各自的兩位上面。

SQL> select row_id, dump(row_id, 16) dump_rowid from test_rowid;


ROW_ID             DUMP_ROWID
------------------ -------------------------------------------------
AAABnRAAGAAAACWAAA Typ=69 Len=10: 0,0,19,d1,1,80,0,96,0,0


如您所列舉的﹕

file id :
SQL> select to_number('0180', 'xxxx')/64 from dual;

TO_NUMBER('0180','XXXX')/64
------------------------
                     6
這個就是 相對文件 ID 了。


block id ﹕
SQL> select to_number('96', 'xxx') from dual;


TO_NUMBER('96','XXX')
---------------------
                  150

就是所在的 塊 id 了。

還有一點沒有清楚﹐為何在算 文件id 時要 除以 /64  以得到文件號才是我們想要的文件。而在算 block 時卻沒有這樣的算。是否這就是您所說的與 文件與塊 "和" 一起存儲的原因﹑

謝謝!

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
22#
 楼主| 发表于 2005-3-20 03:42 | 只看该作者
是的。不知道是由于兼容以前版本还是其他原因,Oracle没有留出足够的空间存储文件号和block号。
文件号和block号合在一起使用了4位来存储。
文件号保存在高两位中,不过文件号在这两位中表示的最小值是4的倍数。这就是为什么需要除以64才能得到正确的值。
而4以下的部分与低两位和在一起用来表示block数。

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34ITPUB元老
日期:2006-09-11 15:36:37
23#
发表于 2005-3-20 17:49 | 只看该作者
謝謝您。。

不過還是有點昏
最初由 yangtingkun 发布
[B]
"文件号保存在高两位中,不过文件号在这两位中表示的最小值是4的倍数。这就是为什么需要除以64才能得到正确的值。
[/B]

"您這句話有點不懂﹐4 的倍數所以除  64 。我理解為 每一位最高能達到16進制的f
所以64=f的4倍﹐即 16*4=64﹐所以要除以 64 ﹖

這樣對嗎﹐不過我感覺有點說不過去﹐因為這樣的話那塊至少也要 除以 16 才對呀。哈....

另外還想請教﹕
最初由 yangtingkun 发布
[B]
"由于BLOCK的值和数据文件共用这4位,因此BLOCK的第3位最大值应小于64,这样才能保证ROWID的不重复。因此BLOCK值的最大值应该是4194304。"
[/B]


block 的第三位最大值應小于 64,您這里所說的第三位 我不理解﹐
像您上面的 文件 id 與 block id 的值為 "1,80,0,96" 第三位我指 存 80的這一位嗎﹖
還是指 rowid ﹕AAABnR  AAG  AAAACW  AAA  中的 存 block AAAACW 中的第三位.

文件id 用兩位在什么情況下才會發生 block 與 file 共用的情況呢﹖

謝謝.

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
24#
 楼主| 发表于 2005-3-21 10:53 | 只看该作者
最初由 zhang_yong88 发布
[B]謝謝您。。

不過還是有點昏

"您這句話有點不懂﹐4 的倍數所以除  64 。我理解為 每一位最高能達到16進制的f
所以64=f的4倍﹐即 16*4=64﹐所以要除以 64 ﹖

這樣對嗎﹐不過我感覺有點說不過去﹐因為這樣的話那塊至少也要 除以 16 才對呀。哈....

另外還想請教﹕


block 的第三位最大值應小于 64,您這里所說的第三位 我不理解﹐
像您上面的 文件 id 與 block id 的值為 "1,80,0,96" 第三位我指 存 80的這一位嗎﹖
還是指 rowid ﹕AAABnR  AAG  AAAACW  AAA  中的 存 block AAAACW 中的第三位.

文件id 用兩位在什么情況下才會發生 block 與 file 共用的情況呢﹖

謝謝. [/B]


哦,是我上面的表达有些问题。
是相对文件号乘以64的结果存放到高位上。
因此,不考虑block的话,那么数据文件的存储编码最小值是0x40(16进制),而且会是64的倍数。
这样,高两位的结果余64的结果,就是block号的高位。当block的数量超过65536时,你就会看到二者共享的情况了。

有时间我做个测试演示一下。

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
25#
发表于 2005-3-21 11:51 | 只看该作者
http://www.anysql.net/article/rowid.html

不知道我这样说有没有明白?

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
26#
 楼主| 发表于 2005-3-21 12:17 | 只看该作者
最初由 d.c.b.a 发布
[B]http://www.anysql.net/article/rowid.html

不知道我这样说有没有明白? [/B]


你通过ROWID的格式说明如何计算相应的DATA_OBJECT_ID、RELATIVE_FNO、BLOCK_NUMBER和ROW_NUMBER。

现在zhang_yong88 不清楚的是Oracle如何用4个字节存储RELATIVE_FNO、BLOCK_NUMBER这两个内容的。
其实我在写那篇文章的时间就感觉没有交代的很清楚,关键是表达能力太差


下午如果有时间的话,我做个测试来说明一下。

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
27#
发表于 2005-3-21 13:09 | 只看该作者
杨兄说的"文件id 用兩位在什么情況下才會發生 block 與 file 共用的情況呢﹖"

我也确实搞混了!

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
28#
 楼主| 发表于 2005-3-21 16:59 | 只看该作者
[PHP]
SQL> select blocks from user_segments where segment_name = 'TEST1';

    BLOCKS
----------
     86016

SQL> select max(rowid), dump(max(rowid)) dump_rowid from test1;

MAX(ROWID)
------------------
DUMP_ROWID
-----------------------------------------------------------------------------------------
AAABy+AAJAAAU5EAAM
Typ=69 Len=10: 0,0,28,190,2,65,78,68,0,12


SQL> select dbms_rowid.rowid_relative_fno('AAABy+AAJAAAU5EAAM'),
  2  dbms_rowid.rowid_block_number('AAABy+AAJAAAU5EAAM') from dual;

DBMS_ROWID.ROWID_RELATIVE_FNO('AAABY+AAJAAAU5EAAM')
---------------------------------------------------
DBMS_ROWID.ROWID_BLOCK_NUMBER('AAABY+AAJAAAU5EAAM')
---------------------------------------------------
                                                  9
                                              85572


SQL> select 9*64, 2*256+65 from dual;

      9*64   2*256+65
---------- ----------
       576        577

SQL> select 1*256*256 + 78*256 + 68 from dual;

1*256*256+78*256+68
-------------------
              85572
.
[/PHP]

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
29#
发表于 2005-3-21 17:20 | 只看该作者
上面的block所在的data_object_id应当是7358吧

rdba = ((2 * 256 + 65) * 256 + 78)  * 256 + 68
高10bit是rfn, 低22bit是block id
slot = 12, 这一行在block中的row index的位置是12行,可以dump看一下.

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
30#
 楼主| 发表于 2005-3-21 17:57 | 只看该作者
最初由 d.c.b.a 发布
[B]上面的block所在的data_object_id应当是7358吧

rdba = ((2 * 256 + 65) * 256 + 78)  * 256 + 68
高10bit是rfn, 低22bit是block id
slot = 12, 这一行在block中的row index的位置是12行,可以dump看一下. [/B]


对是7358。

[PHP]
SQL> select 1*64*64+50*64+62, 28*256+190, dbms_rowid.rowid_object('AAABy+AAJAAAU5EAAM') from dual;

1*64*64+50*64+62 28*256+190 DBMS_ROWID.ROWID_OBJECT('AAABY+AAJAAAU5EAAM')
---------------- ---------- ---------------------------------------------
            7358       7358                                          7358
.
[/PHP]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表