ORACLE存储之NUMBER类型

这篇是关于ORALCE对NUMBER类型存储方式的探析, 以及试图对设计者的初始意图进行解释.

最近往上看了很多对ORACLE怎样进行数据存储进行描述的, 感觉都不好理解, 于是参照了很多文章, 自己琢磨了下几种简单数据类型的存储.

Number类型

ORACLEnumber的存储, 首先是按一定规则进行转换以后以十六进制存储(真正存储当然是二进制, 只是我们dump出来看到的是十六进制).

 

ORACLE数据库中存储的number类型包含3个部分: HEAD部分, DATA部分, 符号位.

对正数来说, 符号位省略, 0来说, 只有80.

首先来看几个存储的例子, 我们可以用

SELECT DUMP(89,16) FROM dual

来看到ORACLEnumber类型实际存储的结果: Typ=2 Len=2: c1, 5a

当然,如果我们想看十进制的,就用

SELECT DUMP(89,10) FROM dual

Typ=2 Len=2: 193, 90

123 à C2, 2, 18

123.123 à C2, 2, 18, D, 1F

0 à 80

-123 à 3D, 64, 4E, 66

-0.123 à 3F, 59, 47, 66

HEAD部分为一个字节8, 表示其大小, 当然也包括正负, 就是前面看到的C2, 3D.

因为设计这种存储格式的时候, 希望以十六进制00-FF来表示所有的number, 所以为了编码的对称, 首先将number分为正负, 所以以00-FF的中间位置80, 也就是十进制的128来表示0, HEAD部分小于80,即为负数,大于80即为正数.

, 一个数, 都可以表示成(+/-)A.B * 10(+-)C, 正负A.B * 10的正负C次方.

所以, ORACLE再次对00-80, 80-FF进行对分.

00-3E表示 x <= -1

3F-7F 表示 -1< x <0

81-C0 表示 0< x < 1

C1-FF 表示 1<= x

 

然后,我们再来看数据部分, ORACLE对十进制的数字是两位两位进行存储的, 例如对1234, ORACLE会分别对12, 34进行存储. 所以只需要对(+-)1-99进行编码

1-99 分别用十六进制2-64表示就是2-100 x=y-1,

-1 – -99用十六进制64 – 2表示就是100-2 x=y-101

 

而位数的话, 就分别以距+-1两个标准(为了方便,我们以下将以十进制来看)3E, C1(62,193)之差来表示. 至于符号位, 网上有人说是为了方便排序, 并且用的是(+-)1-99都不可能用到的编码66(102)来表示.

 

例如123, 我们看为(100+23), 1要多一个百位, 所以HEAD表示为193 + 1 = 194

数据部分用(2, 24)表示, 就是(194,2,24), 转换为十六进制为(C2, 2, 18)

 

123.123, 我们看为(100+23+0.12+0.0030), 同样HEAD部分为194

数据部分成了(2,24,13,31), 所以就是(C2,2,18,D,1F)

 

-123, 我们看为(-100-23), 1多一个百位, 所以HEAD62-1 = 61

数据部分(64, 78), 所以就是(3D, 64, 4E, 66)

 

-0.123, 我们看为(-0.12-0.0030), 最高位比-1少一个百分位, 所以HEAD62+1 = 63

数据部分为(89,71), 所以就是(3F, 59, 47, 66)

 

其余可类推, 其逆过程也很容易知道了.

posted @ 2011-06-10 10:05  郭振斌  阅读(3314)  评论(1编辑  收藏  举报