`
cargoj
  • 浏览: 57912 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Oracle 数据类型及存储方式(二)数值类型

阅读更多

第二部分 数值类型
§ 2.1 number
Number类型是oralce的数值类型,存储的数值的精度可以达到38位。Number是一种变长类型,长度为0-22字节。取值范围为:10e- 130 – 10e 126(不包括)
Number(p,s)
P和s都是可选的。
P指精度(precision),即总位数。默认情况下精度为38。精度的取值范围为1~38.
S指小数位(scale).小数点右边的位数。小数点位数的合法值为-48~127。小数位的默认值由精度来决定。如果没有指定精度,小数位默认为最大的 取值区间.如果指定了精度,没有指定小数位。小数位默认为0(即没有小数位).
精度和小数位不会影响数据如何存储,只会影响允许哪些数值及数值如何舍入。


1.新建一个表
SQL> create table test_number(col_number number(6,2));

Table created
2.插入一些不同的数据
SQL> insert into test_number values(-1);

1 row inserted

SQL> insert into test_number values(0);

1 row inserted

SQL> insert into test_number values(1);

1 row inserted

SQL> insert into test_number values(2);

1 row inserted

SQL> insert into test_number values(11.00);

1 row inserted

SQL> insert into test_number values(11.11);

1 row inserted

SQL> insert into test_number values(1234.12);

1 row inserted

SQL> insert into test_number values(-0.1);

1 row inserted

SQL> insert into test_number values(-11.11);

1 row inserted

SQL> insert into test_number values(-1234.12);

1 row inserted
SQL> commit;

Commit complete

3.查看结果
SQL> select * from test_number;

COL_NUMBER
----------
     -1.00
      0.00
      1.00
      2.00
     11.00
     11.11
   1234.12
     -0.10
    -11.11
-1234.12

10 rows selected

5. 查看存储结构
SQL> select col_number, dump(col_number) from test_number;

COL_NUMBER DUMP(COL_NUMBER)
---------- --------------------------------------------------------------------------------
     -1.00 Typ=2 Len=3: 62,100,102
      0.00 Typ=2 Len=1: 128
      1.00 Typ=2 Len=2: 193,2
      2.00 Typ=2 Len=2: 193,3
     11.00 Typ=2 Len=2: 193,12
     11.11 Typ=2 Len=3: 193,12,12
   1234.12 Typ=2 Len=4: 194,13,35,13
     -0.10 Typ=2 Len=3: 63,91,102
    -11.11 Typ=2 Len=4: 62,90,90,102
-1234.12 Typ=2 Len=5: 61,89,67,89,102

10 rows selected

由此可见:
Number类型的内部编码为:2
根据每一行的len值可以看出,number是一个变长类型。不同的数值占用不同的空间。
如果指定了精度,显示结果与精度相关。
就像我插入语句写为
insert into test_number values(0);
但是显示结果为:0.00
如果数值是负数,在最后一位上填充一个补码102.即表示该数值为负数。
0是一个特殊的值,它在oracle中存储为128.
第一位为标志位。以128为比较。如果数值大于128,则它大于0。如果小于128小于0。
-1的内部存储为:
-1.00 Typ=2 Len=3: 62,100,102
最后一位是102,是一个负数。
第一位小于128,所以小于10.
除了第一位标志位外,其它的都是数值为了。
如果该值是一个正数。每一位的存储值减1为每一位的实际值。
1.0的存储结构为:
1.00 typ=2 Len=2: 193,2
实值上1.00的存储结果与1相同。
第一位193为标志位,大于128,大于0.
第二位为数值为,因为是正数,实际值为存储值减1。2-1 = 1。
如是该值是一个负数,每一位的实际值为101 减去存储的值。
-1.00的存储结构为:
-1.00 Typ=2 Len=3: 62,100,102
最后一位102为补位。
第一位62为标志位,小于128。实际值小于0.
第二位为数值为,因为是负数。实际值为:101 – 100 =1.

§2.2 小数位在哪里?
从上面的存储结果看,对小数存储时,它并没有一个小数的标志位。但是它实际上是由第一位标志位,和数值位(第二位)来决定的。
当存储的数是一个正数,该数值的前几位为:第一位 * power(100 , (标志位 - 193));
当存储的数是一个负数,该数值的前几位为:第一位 * power(100,(62 – 标志位));
11.11的存储结果为:
11.11 Typ=2 Len=3: 193,12,12
第一位数值位为:12 实际数值为11
标志位为:193
12 * power(100, (193- 193);
   100的零次方为1.
12 乘1 等于12.
所以这个数的前几位为:12。从这后面就是小数了。
1234.12的存储结构为:
1234.12 Typ=2 Len=4: 194,13,35,13
第一位数值位为:13,实际值为12
标志位为:193
13 * power(100,(194-193)) = 1300
所以前四位为整数位,后面的为小数位。


-0.10的存储结构为:
-0.10 Typ=2 Len=3: 63,91,102
标志位为:63
第一位数值为:91 ,实际值为:10
91 * (100,(62-63)) =-9100.
所以小数位在91之前。

-1234.12的存储结构为:
-1234.12 Typ=2 Len=5: 61,89,67,89,102
标志位为:61
第一位数值为:89
89*(100,(62-61)) =8900
所以小数位在67之后。
§2.3 number的精度和小数位
Number类型的精度最多可是38位。小数位-84--127位。
SQL> create table test_number1(col_number number(39));

create table test_number1(col_number number(39))

ORA-01727: numeric precision specifier is out of range (1 to 38)
指定小数位时,精度只能是1-38。不能是0
SQL> create table test_number1(col_number number(0,127));

create table test_number1(col_number number(0,127))

ORA-01727: numeric precision specifier is out of range (1 to 38)



SQL> create table test_number1(col_number number(1,128));

create table test_number1(col_number number(1,128))

ORA-01728: numeric scale specifier is out of range (-84 to 127)

精度与小数位的关系。精度并不是小数位加整数位之和。
我们先看看小数位为0的情况。
SQL> create table test_number1(col_char varchar2(200), col_num number(10));

Table created
Number(10).只定义了精度,小数位为0.
看看它可以存放的数据。


SQL> insert into test_number1 values('9999999999',9999999999);

1 row inserted

插入了10个9,没有问题,再插入多一位看看
SQL> insert into test_number1 values('99999999991',99999999991);

insert into test_number1 values('99999999991',99999999991)

ORA-01438: value larger than specified precision allowed for this column

报错了,精度不够。
再看看能不能再插入小数?
SQL> insert into test_number1 values('0.9',0.9);

1 row inserted


SQL> select * from test_number1;

Col_char COL_NUM
-------------------- --------------
9999999999 9999999999
0.9              1

注意插入数值0.9后,存储为1.这就是小数位的作用。在哪里进行舍入。

带小数位和精度的情况。
SQL> create table test_number2(col_char varchar(20),col_num number(1,3));

Table created
精度是1,小数位是3.
可见,精度不是小数位加整数位了。但是精度和小数位倒底什么关系呢?
SQL> insert into test_number2 values('0.111',0.111);

insert into test_number2 values('0.111',0.111)

ORA-01438: value larger than specified precision allowed for this column
插入3位小数,0.111竟然报错了,说精度不够。
SQL> insert into test_number2 values('0.001',0.001);

1 row inserted
插入0.001时,成功了。
SQL> insert into test_number2 values('0.001',0.0015);

1 row inserted
插入0.0015也成功了。
看看插入的值。
SQL> select * from test_number2;

COL_CHAR             COL_NUM
-------------------- -------
0.001                  0.001
0.0015                 0.002
需要注意的是0.0015被舍入为0.002

精度大于小数位
SQL> create table test_number3 (col_char varchar(20), col_number number(5,3));

Table created

SQL> insert into test_number3 values('99.899',99.899);

1 row inserted

SQL> insert into test_number3 values('99.999',99.999);

1 row inserted

SQL> insert into test_number3 values('99.9999',99.9999);

insert into test_number3 values('99.9999',99.9999)

ORA-01438: value larger than specified precision allowed for this column

注意,当插入99.9999时,系统报错。因为小数位为3位。第四位小数位是9,于是往前入。最终变成100.000.就已经超过了精度。
Number(5,3)可存储的数值最大为99.999.
现在终于有点明白小数位与精度的关系了。

number(38,127)
可以存储的最大小数为:127位小数,最后38为9.
即:0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999999999999999999999999999999999999

小数位为负数。
我们从前面知道,小数位的取值为-48 ~127
为什么小数位会为负数?这有点怪异了。像上面的number(5,3)将值舍入为最接近0.001
Number(5,-3)就是将值舍入为最接近的1000

SQL> create table test_number5 (col_char varchar(20), col_num number(5,-3));

Table created

插入值10999
SQL> insert into test_number5 values('10999',10999);

1 row inserted
查看一下结果
SQL> select * from test_number5;

COL_CHAR             COL_NUM
-------------------- -------
10999                  11000
存储的结果为:11000
当小数部分为负数时,是对小数部分进行舍入。

那么精度在这时起到什么作用呢?与小数位又有什么关系?
SQL> insert into test_number5 values('111111111',111111111);

insert into test_number5 values('111111111',111111111)

ORA-01438: value larger than specified precision allowed for this column
插入9个1时,报错精度不够。
SQL> insert into test_number5 values('11111111',11111111);

1 row inserted
插入8个1时,正确插入。
我们看看它的结果,看它是怎么舍入的。
SQL> select * from test_number5;

COL_CHAR             COL_NUM
-------------------- -------
11111111             11111000

结果是1111100而不是1111100
无限接近1000,就是从百位开始进行四舍五入,后面的值全部为0。
所以看出number(5,-3)可存储的最大值为:99999000
SQL> insert into test_number5 values('99999499.999999',99999499.999999);

1 row inserted

SQL> select * from test_number5;

COL_CHAR             COL_NUM
-------------------- -------
99999999             99999000
99999499.999999      99999000

现在应该明白了精度和小数位的关系了吧。
小数位告诉系统保留多少位小数,从哪里开始舍入。
精度舍入后,从舍入的位置开始,数值中允许有多少位。

§2.4 binary_float 和binary_double
这两种类型是oracle 10g新引进的数值类型。在oracle 10g之前是没有这两种类型的。
Number类型是由oracle软件支持的类型。而浮点数用于近似数值。但是它浮点数允许由在硬盘上(CPU,芯片)上执行运行。而不是在oracel 进程中运算。如果希望在一个科学计算中执行实数处理,依赖于硬件的算术运算速度要快得多。但是它的精度却很小。如果希望用来存储金融数值,则必须用 number.
BINARY_FLOAT是一种IEEE固有的单精度浮点数。可存储6位精度,取值范围在~±1038.25的数值。
BINARY_DOUBLE是一种IEEE固有的双精度浮点数。可存储12位精度。取值范围在~±10308.25的数值
SQL> create table test_floatdouble(col_number number, col_float binary_float, col_double binary_double);

Table created

SQL> insert into test_floatdouble values(9876543210.0123456789,9876543210.0123456789,9876543210.0123456789);

1 row inserted
2 SQL> select to_char(col_number), to_char(col_float), to_char(col_double) from test_floatdouble;
3
4 TO_CHAR(COL_NUMBER)                      TO_CHAR(COL_FLOAT)                       TO_CHAR(COL_DOUBLE)
5 ---------------------------------------- ---------------------------------------- ----------------------------------------
6 9876543210.0123456789                    9.87654349E+009                          9.8765432100123463E+009

由此可见,binary_float无法表示这个数。Binary_float和binary_double无法用于对精度要求高的数据。



SQL> select dump(col_float)from test_floatdouble;

DUMP(COL_FLOAT)
--------------------------------------------------------------------------------
Typ=100 Len=4: 208,19,44,6

BINARY_FLOAT 类型编码为100
Len=4 占用4个字节。它是采用固定字节进行存储的。

SQL> select dump(col_double)from test_floatdouble;

DUMP(COL_DOUBLE)
--------------------------------------------------------------------------------
Typ=101 Len=8: 194,2,101,128,183,80,25,73

BINARY_DOUBLE 类型编码为101
Leng= 8 占用8个字节。也是采用固定字节进行存储。

注意:number 类型使用的CPU时间是浮点数类型的50倍。浮点数是数值的一个近似值,精度在6-12位之间。从Number类型得到的结果要比从浮点数得到的结果更精 确。但在对科学数据进行数据挖掘和进行复杂数值分析时,精度的损失是可以接受的,还会带来显著的性能提升。
这时需要使用内置CAST函数,对NUMBER类型执行一种实时的转换,在执行复杂数学运算之前先将其转换为一种浮点数类型。CPU使用时间就与固有浮点 类型使用的CPU时间非常接近了。
Select ln(cast(number_col as binary_double)) from test_number.

§2.5 Oracle在语法上还支持的数值数据类型
NUMERIC(p,s):完全映射到NUMBER(p,s)。如果p未指定,则默认为38.
DECIMAL(p,s)或DEC(p,s):同NUMERIC(p,s).
INTEGER或int:完全映射至NUMBER(38)
SMALLINT:完全映射至NUMBER(38)
FLOAT(b):映射至NUMBER
DOUBLE PRECISION:映射到NUMBER
REAL:映射到NUMBER.

分享到:
评论

相关推荐

    Oracle 数据类型

    7、LOB数据类型用于存储大型的,没有被结构化的数据,例如二进制文件,图片文件,LOB主要分为BLOB和CLOB,BLOB数据类型用于存储二进制对象:图像,音频,视频...CLOB数据类型用于存储字符格式的大型对象 8、ORACLE...

    Oracle 从入门到精通视频教程(11G版本)(ppt)

    Oracle 11g中支持的数据类型 数据库定义语言(DDL) 约束的使用 数据操纵语言(DML) 第5章-利用SELECT检索数据 SQL-数据库沟通的语言标准 Oracle 11g中支持的数据类型 数据库定义语言(DDL) 约束的使用 ...

    Oracle Number型数值存储与转换的实现详解

    Oracle在数据库内部通过相应的算法转换来进行数据存储,本文简单介绍Oracle的Number型数值存储及转换.这个内容是为了回答留言板上的2119号问题.我们可以通过DUMP函数来转换数字的存储形式,一个简单的输出类似如下格式...

    oracle database 10g 完整参考手册part1

    第42章 Oracle数据字典指南 第43章 调整应用程序和SQL旅行者指南 第44章 调整中的案例分析 第45章 Oracle Application Server 10g的旅行者指南 第46章 数据库管理旅行者指南 第47章 XML旅行者指南

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    其三、职业方向多:Oracle数据库管理方向、Oracle开发及系统架构方向、Oracle数据建模数据仓库等方向。 四、 如何学习 认真听课、多思考问题、多动手操作、有问题一定要问、多参与讨论、多帮组同学 五、 体系结构 ...

    Oracle_Database_11g完全参考手册.part3/3

    第45章 Oracle数据字典指南 第46章 应用程序和SQL调整指南 第47章 SQL结果缓存和客户端查询缓存 第48章 关于调整的示例分析 第49章 高级体系结构选项——DB保险库、内容DB和记录DB 第50章 Oracle实时应用群集 第51章...

    oracle database 11g 高清完整中文版part2

     第45章 oracle 数据字典指南  第46章 应用程序和sql 调整指南  第47章 sql 结果缓存和客户端查询缓存  第48章 关于调整的示例分析  第49章 高级体系结构选项—— db保险库、内容db 和记录db  第50章 oracle ...

    Oracle_Database_11g完全参考手册.part2/3

    第45章 Oracle数据字典指南 第46章 应用程序和SQL调整指南 第47章 SQL结果缓存和客户端查询缓存 第48章 关于调整的示例分析 第49章 高级体系结构选项——DB保险库、内容DB和记录DB 第50章 Oracle实时应用群集 第51章...

    Oracle数据库、SQL

    6.1数值类型 11 6.2日期类型 11 6.3字符类型 13 6.4转换函数 14 6.5其他注意事项 14 七、 SQL语句中的分支 15 7.1分支表达式 15 7.2分支函数 15 八、 组函数 16 8.1报表统计常用 16 8.2缺省情况组函数处理什么值 16 ...

    Oracle 9i&10g编程艺术:深入数据库体系结构(全本)含脚本

    12.1 Oracle数据类型概述 491 12.2 字符和二进制串类型 494 12.2.1 NLS概述 494 12.2.2 字符串 497 12.3 二进制串:RAW类型 504 12.4 数值类型 506 12.4.1 NUMBER类型的语法和用法 509 12.4.2 BINARY_FLOAT/...

    零点起飞学Orale.pdf

     第2篇 Oracle数据查询(第3~10章)  本篇主要内容包括查询数据表、更新数据表、处理字符型数据、处理数值型数据、处理日期型数据、数据的复杂处理、流程控制语句、使用视图等内容。通过本篇的学习,读者可以掌握...

    神通数据库-数据库快速入门.pdf

    神通数据库所支持的数据类型包括:字符串类型、位串类型、精确数值类型、布尔型、近似数值类型、 日期类型、时间间隔类型、货币类型、二进制大对象、字符型大对象等。 • 提供功能强大的内置函数 神通数据库系统提供...

    Oracle 10g 开发与管理

    1. 数据类型 26 (1)字符型 26 (2)数值型 26 (3)日期时间型 26 (4)LOB (大型对象) 26 (5)RowID (伪列类型) 27 2. 创建表 27 (1)Create Table 表名 27 (2)在原来已有表上建一个新表(结构和数据) 27 ...

    oracle数据库笔记

    1. 数据类型 26 (1)字符型 26 (2)数值型 26 (3)日期时间型 26 (4)LOB (大型对象) 26 (5)RowID (伪列类型) 27 2. 创建表 27 (1)Create Table 表名 27 (2)在原来已有表上建一个新表(结构和数据) 27 ...

    mysql面试题,MySQL是一种关系型数据库管理系统,由Oracle公司开发

    3. MySQL的数据类型有哪些? 答:数值型(整数、小数)、日期型、字符串型、布尔型等 4. MySQL的索引有哪些? 答:主键索引、唯一索引、普通索引 5. MySQL的事务有哪些级别? 答:读未提交(READ UNCOMMITTED)、读已提交...

    oracle database 11g 完整参考手册中文高清完整版part3

     第45章 oracle 数据字典指南  第46章 应用程序和sql 调整指南  第47章 sql 结果缓存和客户端查询缓存  第48章 关于调整的示例分析  第49章 高级体系结构选项—— db保险库、内容db 和记录db  第50章 oracle ...

    oracle database 11g完全参考手册 高清完整版part1 共3部分

     第45章 oracle 数据字典指南  第46章 应用程序和sql 调整指南  第47章 sql 结果缓存和客户端查询缓存  第48章 关于调整的示例分析  第49章 高级体系结构选项—— db保险库、内容db 和记录db  第50章 oracle ...

    Oracle9i的init.ora参数中文说明

    说明: 与 NLS_TIME_FORMAT 相似, 只不过它设置的是 TIMESTAMP 数据类型的默认值, 该数据类型既存储YEAR, MONTH 和 DAY 这几个日期值, 也存储 HOUR, MINUTE 和 SECOND 这几个时间值。 语法: TIMESTAMP '1997-01-31 ...

    Oracle编程艺术

    3.4.2 Oracle数据库中的存储层次体系..............................................181 3.4.3 字典管理和本地管理的表空间..................................................186 3.5 临时文件..........

    SQL必知必会(第3版 中文高清版)

    第1章 了解sql  第2章 检索数据  第3章 排序检索数据  第4章 过滤数据  第5章 高级数据过滤  第6章 用通配符进行过滤  第7章 创建计算字段  ... d.4 二进制数据类型  附录e sql保留字  索引

Global site tag (gtag.js) - Google Analytics