oracle的number的浅析
author:skate
time:2011-02-14
oracle的number的浅析
从例如以下几个方面来认识number
1.表示的数值范围
2.占用的存储空间
3.number的性能
我们日常主要定义数值存储列是大都是用number,只是oracle也兼容一些以他类型,例如以下:
NUMERIC(p,s):全然映射至NUMBER(p,s)。假设p未指定,则默觉得38.
DECIMAL(p,s)或DEC(p,s):全然映射至NUMBER(p,s)。假设p为指定,则默觉得38.
INTEGER或INT:全然映射至NUMBER(38)类型。
SMALLINT:全然映射至NUMBER(38)类型。
FLOAT(b):映射至NUMBER类型。
DOUBLE PRECISION:映射至NUMBER类型。
REAL:映射至NUMBER类型。
以上这些类型仅仅是oracle在语法上支持的,在底层实际上还是number
1.表示的数值范围
NUMBER:Oracle NUMBER类型能以极大的精度存储数值,详细来讲,精度可达38位。其底层数据格式相似一种
“封包小数“表示。Oracle NUMBER类型是一种变长格式,长度为0~22字节。它能够存储小到10e-130、
大到(但不包含)10e126的不论什么数值。这是眼下最为经常使用的数值类型。也是Oracle9i Release 2及以
前的版本号仅仅支持的唯一一种适合存储数值数据的固有数据类型,其它一起兼容类型仅仅是一种和number
之间的映射,在底层实际上都是number
BINARY_FLOAT:这是一种IEEE固有的单精度浮点数。它在磁盘上会占用5字节的存储空间:当中4个固定字节用
于存储浮点数,另外另一个长度字节。BINARY_FLOAT能存储有6为精度、范围在~±1038.53
的数值
BINARY_DOUBLE:这是一种IEEE固有的双精度浮点数。它在磁盘上会占用9字节的存储空间:当中8个固定字节用
于存储浮点数,另一个长度字节。BINARY_DOUBLE能存储有12.位精度、范围在~±10308.25的
数值。
取值范举例:
创建測试表t2
SQL> create table t2
2 ( num_type number,
3 float_type binary_float,
4 double_type binary_double
5 );
Table created
插入測试数据1
SQL>
SQL> insert into t2
2 (num_type, float_type, double_type)
3 values
4 (1234567890.0987654321, 1234567890.0987654321, 1234567890.0987654321);
1 row inserted
查看測试数据1
SQL>
SQL> select to_char(num_type),
2 to_char(float_type, '999999999999.999999999'),
3 to_char(double_type, '99999999999.9999999999')
4 from t2
5 ;
TO_CHAR(NUM_TYPE) TO_CHAR(FLOAT_TYPE,'9999999999 TO_CHAR(DOUBLE_TYPE,'999999999
--------------------------- -----------------------------------------------------------------------------------
1234567890.0987654321 1234567940.000000000 1234567890.0987654000
插入測试数据2
SQL>
SQL> insert into t2
2 (num_type, float_type, double_type)
3 values
4 (12345678900987654321, 12345678900987654321, 12345678900987654321);
1 row inserted
查看測试数据2
SQL>
SQL> select to_char(num_type),
2 to_char(float_type, '999999999999999999999'),
3 to_char(double_type, '999999999999999999999')
4 from t2
5 ;
TO_CHAR(NUM_TYPE) TO_CHAR(FLOAT_TYPE,'9999999999 TO_CHAR(DOUBLE_TYPE,'999999999
---------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1234567890.0987654321 1234567940 1234567890
12345678900987654321 12345679400000000000 12345678900987654000
SQL>
从測试结果能够看到,number能够正确显示数据,精度非常高;binary_float仅仅正确的显示了前7位;binary_double显示的数据范围和精度要比binary_float高非常多。
2.占用的存储空间
number类型占用0-22个字节,它实际上是磁盘上的一个变长数据类型,是oracle依据一定算法,採用尽可能少存储空间表示一个数
SQL> create table t ( x number, y number );
Table created
SQL>
SQL> insert into t ( x )
2 select to_number(rpad('9',rownum*2,'9'),'999999999999999999999999999999999999999999999999999999999')
3 from all_objects
4 where rownum <= 25;
25 rows inserted
SQL> update t set y = x+1;
25 rows updated
SQL> column 数字1 format 9999999999999999999999999999999999999999999999999999999999999999999999999
SQL> column 数字2 format 9999999999999999999999999999999999999999999999999999999999999999999999999
SQL> select to_char(x) 数字1, to_char(y) 数字2, vsize(x) 数字1占字节数, vsize(y) 数字2占字节数 from t order by x;
数字1 数字2 数字1占字节数 数字2占字节数
----------------------------------------------- ------------------------------------------------------------------------- ------------- -------------
99 100 2 2
9999 10000 3 2
999999 1000000 4 2
99999999 100000000 5 2
9999999999 10000000000 6 2
999999999999 1000000000000 7 2
99999999999999 100000000000000 8 2
9999999999999999 10000000000000000 9 2
999999999999999999 1000000000000000000 10 2
99999999999999999999 100000000000000000000 11 2
9999999999999999999999 10000000000000000000000 12 2
999999999999999999999999 1000000000000000000000000 13 2
99999999999999999999999999 100000000000000000000000000 14 2
9999999999999999999999999999 10000000000000000000000000000 15 2
999999999999999999999999999999 1000000000000000000000000000000 16 2
99999999999999999999999999999999 100000000000000000000000000000000 17 2
9999999999999999999999999999999999 10000000000000000000000000000000000 18 2
999999999999999999999999999999999999 1000000000000000000000000000000000000 19 2
99999999999999999999999999999999999999 100000000000000000000000000000000000000 20 2
9999999999999999999999999999999999999999 1.0000000000000000000000000000000000E+40 21 2
数字1 数字2 数字1占字节数 数字2占字节数
--------------------------------------------------------------------------------------------------- ------------- -------------
1.0000000000000000000000000000000000E+42 1.0000000000000000000000000000000000E+42 2 2
1.0000000000000000000000000000000000E+44 1.0000000000000000000000000000000000E+44 2 2
1.0000000000000000000000000000000000E+46 1.0000000000000000000000000000000000E+46 2 2
1.0000000000000000000000000000000000E+48 1.0000000000000000000000000000000000E+48 2 2
1.0000000000000000000000000000000000E+50 1.0000000000000000000000000000000000E+50 2 2
25 rows selected
SQL>
从样例能够看出,在oracle存储有效数据(非0数据)时,每添加两位数,数据的存储空间就添加一个字节,直到数据溢出。
Oracle存储一个数时,会存储尽可能少的内容来表示这个数。为此会存储有效数字和用于指定小数点位置的一个指数,以及
有关数值符号的信息(正或负)。因此,数中包括的有效数字越多,占用的存储空间就越大。
BINARY_FLOAT与BINARY_DOUBLE
浮点数用于近似数值;它们没有Oracle内置的 NUMBER类型那么精确。浮点数经常使用在科学计算中,因为同意在硬件(CPU、芯片)
上运行运算,而不是在Oracle子例程中运算,所以在多种不同类型的应用中都非常实用。因此,假设在一个科学计算应用中运行
实数处理,算术运算的速度会快得多。
BINARY_FLOAT在磁盘上会占用5字节的存储空间:当中4个固定字节用于存储浮点数,另外另一个长度字节
BINARY_DOUBLE在磁盘上会占用9字节的存储空间:当中8个固定字节用于存储浮点数,另外另一个长度字节
3.number的性能
Oracle NUMBER类型对大多数应用来讲都是最佳的选择,尤其是经融行业,只是有利必有弊,number会带来性能的影响。
由于Oracle NUMBER类型是一种软件数据类型,是在Oracle软件本身中实现。我们不能使用固有硬件操作将两个NUMBER
类型相加,这要在软件中模拟,所以性能有非常大的影响,为此,oracle又提供的两个浮点类型的BINARY_FLOAT与BINARY_DOUBLE。
以下举例说明性能对照
创建測试表
SQL> create table t2
2 ( num_type number,
3 float_type binary_float,
4 double_type binary_double
5 );
Table created
SQL>
SQL> insert /*+ APPEND */ into t2
2 select rownum, rownum, rownum
3 from all_objects
4 ;
57302 rows inserted
SQL> alter session set events '10046 trace name context forever ,level 1';
Session altered
SQL> select sum(ln(num_type)) from t2;
SUM(LN(NUM_TYPE))
-----------------
570510.312356972
SQL> select sum(ln(float_type)) from t2;
SUM(LN(FLOAT_TYPE))
-------------------
570510.31235697
SQL> select sum(ln(double_type)) from t2;
SUM(LN(DOUBLE_TYPE))
--------------------
570510.31235697
SQL> select sum(ln(cast(num_type as binary_double ) )) from t2;
SUM(LN(CAST(NUM_TYPEASBINARY_D
------------------------------
570510.31235697
SQL> alter session set events '10046 trace name context off ';
Session altered
SQL>
查看跟踪文件内容例如以下:
........
********************************************************************************
select sum(ln(num_type))
from
t2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 3 1 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 2.31 2.25 38 193 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 2.31 2.25 38 196 1 1
********************************************************************************
select sum(ln(float_type))
from
t2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.04 0.04 0 193 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.04 0.04 0 194 0 1
********************************************************************************
select sum(ln(double_type))
from
t2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.03 0.04 0 193 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.04 0.04 0 194 0 1
********************************************************************************
select sum(ln(cast(num_type as binary_double ) ))
from
t2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.10 0.09 0 193 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.10 0.10 0 194 0 1
从測试结果来看,number的性能确实非常慢,比浮点类型BINARY_FLOAT与BINARY_DOUBLE慢57倍多,只是能够cast函数来转换下,
在对number运行复杂数学运算之前先将其转换为一种浮点数类型,这样就会提高计算速度,但还是比直接用浮点类型慢非常多,
但也是一个折中的方法。
--------end-------
oracle的number的浅析的更多相关文章
- 【转】oracle数据库NUMBER数据类型
原文:http://www.jb51.net/article/37633.htm NUMBER ( precision, scale)a) precision表示数字中的有效位;如果没有指定prec ...
- oracle的resetlogs机制浅析
oracle的resetlogs机制浅析 alter database open resetlogs 这个命令我想大家都很熟悉了,那有没有想过这个resetlogs选项为什么要用?什么时候用?它的原理 ...
- Oracle类型number与PG类型numeric对比和转换策略
Oracle 11g number 任意精度数字类型 http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT3 ...
- 对于Oracle中Number类型的字段映射成Java中的具体类型的问题
我在Oracle中给一个用户Id字段设置为Number类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer.但事实是,我在测试的时候 ...
- Oracle数据库 number 长度与 Short Integer Long BigDecimal 对应关系
转自:https://blog.csdn.net/edward9145/article/details/21398657 Oracle数据库 number 长度与 Short Integer Long ...
- Oracle的number数据类型
https://www.cnblogs.com/oumyye/p/4448656.html NUMBER ( precision, scale) precision表示数字中的有效位;如果没有指定pr ...
- ORACLE 中NUMBER类型默认的精度和Scale问题
在ORACLE数据库中,NUMBER(P,S)是最常见的数字类型,可以存放数据范围为10^-130~10^126(不包含此值),需要1~22字节(BYTE)不等的存储空间.P 是Precison的英文 ...
- Oracle中number(5,-2)数据类型
举个例子,1234.345 如果为number(5,-2),那么结果为 1200, 如果为number(5,2),那么结果为 1234.35 如果为number(5),那么结果为 1234 说明: N ...
- Spark SQL读取Oracle的number类型的数据时精度丢失问题
Spark SQL读取数据Oracle的数据时,发现number类型的字段在读取的时候精度丢失了,使用的spark版本是Spark2.1.0的版本,竟然最后经过排查和网上查资料发现是一个bug.在Sp ...
随机推荐
- bootstrap课程2 bootstrap的栅格系统的主要作用是什么
bootstrap课程2 bootstrap的栅格系统的主要作用是什么 一.总结 一句话总结:响应式布局(就是适应不同的屏幕,手机,平板,电脑) 1.bootstrap的栅格系统如何使用? row ...
- 关于Linux启动时挂载rootfs的几种方式
一直对Linux启动时挂载根文件系统的过程存在着很多疑问,今天在水木精华区找到了有用的资料,摘录如下: 1.Linux启动时,经过一系列初始化之后,需要mount 根文件系统,为最后运行init进程等 ...
- POJ 1384 Piggy-Bank (ZOJ 2014 Piggy-Bank) 完全背包
POJ :http://poj.org/problem?id=1384 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode ...
- POJ 题目2506Tiling(大数)
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8128 Accepted: 3941 Descriptio ...
- QMap 的增删改查
map 是一种数据容器,它提供一种由key 到 value 的映射.map 的key 是唯一的, 也是有序的.map 通常由近似平衡的红黑树来实现.key 的有序性,使得插入,查找节点比较有效.map ...
- css3-10 css3中的边框样式有哪几种
css3-10 css3中的边框样式有哪几种 一.总结 一句话总结:1.border-radius 2. box-shadow 3.border-image三种,box一种border两种 1.css ...
- 在Linux上安装及配置MariaDB
安装MariaDB 1.切换到root用户,首先执行rpm -qa | grep -i mysql检查一下是否有已安装的与MySQL相关的东西,如果有,使用rpm -e --nodeps mysql* ...
- 【40.17%】【codeforces 569B】Inventory
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- [Ramda] Compose lenses
We can compose lenses to get value: const addrs = [{street: '99 Walnut Dr.', zip: '04821'}, {street: ...
- cat /proc/cpuinfo 引发的思考--CPU 物理封装-物理核心-逻辑核心-超线程之间关系
CPU的物理封装,一个物理封装使用独立的一个CPU物理插槽,共享电源和风扇: CPU物理核心:在一个物理封装中封装了多个独立CPU核心,每一个CPU核心都有自己独立的完整硬件单元. CPU逻辑核心:一 ...