oracle数据库和其他库存储Number类型数据有比较大的区别。例如Mysql,有点类似于程序语言,会有明确的区分,如int,float等。Oracle的Number就一种存储格式,float也没有采用IEEE标准(所以也没有谁说Oracle有浮点数精度问题)。Oracle是采用了类似于按位拆分,将10进制数字拆分为两个一组,存到一个字节中,一个字节最大128嘛,存个两位数还是足够的。整数和小数分开存储,再加上一些长度位,标识位,符号位,就OK了。
理了一个示意图,便于理解
注意: 二进制位那一行的数字仅示例表示位的下标索引,无实际意义
下面举几个例子
正整数 如: 123
从右向左拆分,两个一组 可拆成两组 1和23 那么存两位字节的整数,分别是 02 和24(都加1,可能是因为 不加1会出现0,0在二进制中一般表示结束符);
标识位就是 0xC0+2(整数长度) 即0xC2 = 194
无小数部分,正数省略符号位
那么长度位就是 3 (标识位+整数部分)
(注意,长度位有大小端的区别,不了解大小端的,可以自行百度)
存储成二进制就是 03 00 194 02 24
正数带小数 如: 1.234
整数部分按前面的规则,仅1位 存 02
紧跟着小数部分,从左往右,2位一组 即需要存 23 和40(注意,不是4) 分别就是24和41
正数省略符号位
标识位就是 0xC0+1 即0xC1 = 193
那么长度位就是 4(标识位+整数部分+小数部分 即 1+1+2)
存储成二进制就是 04 00 193 2 24 41
负整数 如 -123
整数部分拆为 1和23,转换后为 100和78 (注意,当为负数时,不是+1,而是拿101减)
无小数部分
标识位就是 0x3F-2 即0x3D = 61
负数末尾符号位为 0x66, 即 102
长度为 1+2+1(符号位) 为4
存储成二进制就是 04 00 61 100 78 102
负数带小数 如 -1.234
整数部分拆为 1,转换后为 100
小数部分为两组 23 和 40 即为 78 和 61
标识位就是 0x3F-1 即0x3E = 62
负数末尾符号位为 0x66, 即 102
长度为 1+1+2+1(符号位) 为5
存储成二进制就是 05 00 62 100 78 61 102
零值: 0
直接就是 01 00 128(0x80的十进制是128)
个人理解,Oracle在存储Number上,尤其是int这些强类型,性能肯定没有其他库快。但是查询时,例如值比较,会非常快,因为不需要比全部。 例如比较两个正整数,标识为这一个字节谁大,那么那个值就大,哪怕一样,逐个往后比单字节就行。 作为where条件还是很理想的。