读书笔记:**Oracle 中的数字类型:怎么选?怎么用?**

我们的文章会在微信公众号IT民工的龙马人生博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。

本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。

Oracle 中的数字类型:怎么选?怎么用?

Oracle 数据库提供了三种主要的数字类型,它们各有特点,适用于不同的场景。简单来说:

  1. NUMBER 类型

    • 特点:精度超高,最多能存 38 位有效数字。比如可以存非常小的数(像 10 的 -130 次方),也可以存非常大的数(接近 10 的 126 次方)。
    • 存储:它在磁盘上占用的空间是可变的(0 到 22 字节),存的数字有效位数越多,占的空间就稍微大一点。
    • 适用场景:这是最常用的数字类型,尤其适合需要精确计算的场景,比如金融、财务等领域的金额和数值。
  2. BINARY_FLOAT 类型

    • 特点:单精度浮点数,遵循 IEEE 标准。能存的范围很大(约 ±10^38.53),但精度较低,只有大约 6 位有效数字。
    • 存储:固定占用 5 字节存储空间。
    • 注意:可能会丢失精度,不适合存需要精确计算的数字。
  3. 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)

posted @ 2025-10-10 14:27  认真就输  阅读(15)  评论(0)    收藏  举报