我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。
Oracle 中的数字类型:怎么选?怎么用?
Oracle 数据库提供了三种主要的数字类型,它们各有特点,适用于不同的场景。简单来说:
-
NUMBER 类型:
- 特点:精度超高,最多能存 38 位有效数字。比如可以存非常小的数(像 10 的 -130 次方),也可以存非常大的数(接近 10 的 126 次方)。
- 存储:它在磁盘上占用的空间是可变的(0 到 22 字节),存的数字有效位数越多,占的空间就稍微大一点。
- 适用场景:这是最常用的数字类型,尤其适合需要精确计算的场景,比如金融、财务等领域的金额和数值。
-
BINARY_FLOAT 类型:
- 特点:单精度浮点数,遵循 IEEE 标准。能存的范围很大(约 ±10^38.53),但精度较低,只有大约 6 位有效数字。
- 存储:固定占用 5 字节存储空间。
- 注意:可能会丢失精度,不适合存需要精确计算的数字。
-
BINARY_DOUBLE 类型:
- 特点:双精度浮点数,同样遵循 IEEE 标准。能存的范围极大(约 ±10^308.25),精度比 BINARY_FLOAT 高,有大约 13 位有效数字。
- 存储:固定占用 9 字节存储空间。
- 注意:同样可能存在精度丢失问题。
一句话总结:NUMBER 精度高,BINARY_ 范围大但可能不精确。*
举个例子就明白了
我们建一张表,用三种类型存同一个数 1234567890.0987654321
,看看结果:
CREATE TABLE t (num_col NUMBER,float_col BINARY_FLOAT,dbl_col BINARY_DOUBLE
);INSERT INTO t VALUES (1234567890.0987654321,1234567890.0987654321,1234567890.0987654321);SELECT * FROM t;
查询结果:
NUM_COL | FLOAT_COL | DBL_COL |
---|---|---|
1234567890.0987654321 | 1234567940.0000000000 | 1234567890.0987654000 |
你看:
- num_col (NUMBER):原封不动,完全准确地存下来了。
- float_col (BINARY_FLOAT):精度丢失严重,后几位都变成 0 了。
- dbl_col (BINARY_DOUBLE):好很多,但最后两位还是丢掉了。
所以,如果你在做钱相关的计算,千万别用 BINARY_FLOAT 和 BINARY_DOUBLE!
深入了解 NUMBER 类型
定义 NUMBER 类型的列时,可以指定两个参数:NUMBER(p, s)
p
表示 精度,即数字总共的有效位数(最大 38)。s
表示 小数位数,即小数点右边的位数。
这两个参数有什么用?
它们主要是数据校验和舍入规则,并不影响数据在磁盘上的物理存储方式。
-
精度 (p) 是约束:它规定了数字最多不能超过多少位。超了就会报错。
CREATE TABLE t (num_col NUMBER(5,0)); -- 最多存5位整数 INSERT INTO t VALUES (12345); -- 成功 INSERT INTO t VALUES (123456); -- 失败!报错 ORA-01438
-
小数位 (s) 管舍入:它规定了一个数字要如何四舍五入。
CREATE TABLE t (num_col NUMBER(5,2)); -- 总共5位,其中2位是小数 INSERT INTO t VALUES (123.456); -- 成功,会自动四舍五入为 123.46 INSERT INTO t VALUES (1234.00); -- 失败!整数部分超了(5位精度=3位整数+2位小数)
-
s 也可以是负数:这表示要把数字四舍五入到小数点左边的指定位数(十位、百位等)。
CREATE TABLE t (num_col NUMBER(5,-2)); -- 精确到百位 INSERT INTO t VALUES (123.45); -- 会被四舍五入为 100 INSERT INTO t VALUES (1234567); -- 会被四舍五入为 1234600 INSERT INTO t VALUES (12345678); -- 失败!四舍五入后是12345700,超过5位了
关于 NUMBER 类型的存储空间
关键一点:NUMBER 是变长的,不是定长的。
它占用的空间取决于你存的数字有多大(有效位数有多少)。数字的有效位数越多,占用的字节就稍微多一点(大致每2位有效数字多占1字节)。Oracle 会尽量用最节省空间的方式来存。
这对我们有什么影响?
当你设计表并估算这张表未来会占多大磁盘空间时,对于 NUMBER 列,你不能简单地按“最大可能”来算,那样会高估。也不能按“最小可能”来算,那样会低估。最好能有一些代表性的真实数据来估算平均大小。
希望这篇文章能帮你更好地理解和使用 Oracle 的数字类型!
------------------作者介绍-----------------------
姓名:黄廷忠
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)