【inernal】oracle中number类型存储解析

首先需要回答的两个问题。

1、number类型跟指定精度的number类型相比是否浪费存储空间?

   number类型不指定精度即相当于设置了number的最大精度(38位)。

   number类型的实际存储机制与varchar雷同,即存储多少数据占用多少空间。

   number类型下存储的23.23和number(9,3)下存储的23.23都是一样的。

   所以绝大多数情况下number类型和指定精度的number类型在存储空间上无区别。

  

   但存储无限小数就不同了。比如1/3.

   存储在number类型,会保留38位精度的小数(0.33333333333333333333333333333333333333)。

   存储在number(9,3)类型中,则会是(0.333)

   两者存储的数据本身不同,占用的空间自然就不同了。

2、若是存储数据超过列定义时指定的精度,oracle会如何处理?

   高位不够存储会报错。

   低位不够存储则四舍五入。

3、关于int、decimal等数字类型

    oracle支持int、decimal等类型,但仅仅是为了兼容其他数据库,实际oracle在内部使用和存储的时候,这些类型都会是number类型。

 

回答了以上两个问题就可以实际验证下了。

 

说下定义

number(precision,scale)

1、precision即有效数位,取值范围为【1--38】。可以理解存储数的长度(第一个非零开始到最后一个非零结束)

    从后面的存储部分可以知道,每1byte存储两位,38位共需要19byte的存储空间。

2、scale即比例,取值范围为【-84--127】,是小数点后保留的长度。可以为负,标识小数点前舍入的长度。

    从后面的存储部分可以知道,scale对应的最高位标识,使用了1byte(8位)存储,所以取值范围为-84--127.

3、若插入数据不符合规则定义,

    对于高位不够存储的,会报错。

   对于低位不够存储的,则四舍五入。

4、可插入的整数部分最大长度为(从正数部分第一个不为0的数位到各位,与precision中的存储长度区别下)为precision- scale。

   比如我存储1230(长度为4)到number(4,1)则会报错,因为4-1=3>4.存储在number(3,-1)则没问题,因为3-(-1)=4=4.

 

 

说下存储


1、number类型存储方式如上图,共分三个部分,最高位标识、数据部分和正负标识。

2、数字0只有最高标识位,为0x80。

3、最高位标识,占用1byte,标识数字的第一个不为0的数字的进制位(每一个标识位标识两个进制位)。

    正数和负数的最高标示为不同。

    正数标示为大于0x80的数字,负数标示为小于0x80的数字。

        对于正数

        个位、十位标示为c1,百位、千位标示为c2.....

   十分位、百分位标示为c0,千分位、万分位标识位bf....

   对于负数

         ........具体可见下图。


   

4、数据部分

     数据部分每1byte标识2位数。所以每1byte标识的数字范围为1-99.

     正数和负数的数字表示不同,

        对于正数,0x01--0x64(正序)标识1-99,其中0x标识比数字实际对应的十六进制数大1.比如0x02标识数字1,0x03标识数字2。

        对于负数,0x65--0x2(倒序)标识1-99,其中0x64标识数字1,0x63标识数字2.

5、符号位

       正数符号位为空,负数的符号位存储为0x66。

       经验证,只有当输入有效数字的长度大于38的时候,负数标识66将不存在(最高标识位可判断正负,所以这里我理解这个66是作了一个正负标识的冗余)。

说下验证方法

     对于不超过38位精度的数字,可以使用dump查看存储

         select dump(to_number(1),16) from dual;

 

        对于超过38位精度的数,就只能dump数据块查看了。

         alter systemdump datafile 1 block 123;

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值