我们来详细讲解一下 Oracle 中的 NUMBER 数据类型。它是 Oracle 中最常用、最核心的数值型数据类型,以其高精度和灵活性而著称。
1. 概述
NUMBER 数据类型用于存储零、正负定点数或浮点数。它的最大特点是精度可变,并且可以进行高精度的计算,非常适合需要精确计算的场景,如金融、科学计算等。
2. 语法定义
在创建表时,定义 NUMBER 列的语法如下:
NUMBER[(precision [, scale])]
- precision(精度): 指数字的总位数,包括小数点左边和右边的所有数字。它的范围是 1 到 38。
- scale(标度): 指小数点右边的最大位数。它的范围是 -84 到 127。
根据 precision 和 scale 的不同,NUMBER 可以表现为几种不同的形式。
3. 各种形式的含义与示例
| 定义方式 | 含义 | 输入值 | 实际存储值 | 解释 |
|---|---|---|---|---|
| NUMBER | 最大精度和标度 | 12345.6789 | 12345.6789 | 不指定精度和标度,可以存储任何38位以内的数字,完全保留精度。 |
| NUMBER(precision) | 定点数 | 1234.567 | 1235 | 指定总位数,小数部分会四舍五入到整数。precision=4,1234.567 四舍五入为 1235。 |
| NUMBER(precision, scale) | 定点数 | 123.456 | 123.46 | 最常见的形式。precision=5, scale=2,总位数5位,小数2位。123.456 四舍五入为 123.46。 |
| NUMBER(precision, -scale) | 舍入到小数点左边 | 12345.67 | 12300 | scale 为负数时,会四舍五入到小数点左边指定的位数。precision=5, scale=-2 表示四舍五入到百位。 |
| NUMBER(*, scale) | 限制小数位,不限制总位数 | 123456.789 | 123456.79 | 忽略总位数 (*),只限制小数位数。scale=2,所以 123456.789 四舍五入为 123456.79。 |
特殊情况:
- 如果
scale是负数,例如NUMBER(10, -2),它表示数字被四舍五入到小数点左边的两位(即百位)。输入555会存储为600。 - 如果实际存储的整数部分超出了
(precision - scale)允许的位数,Oracle 会报错ORA-01438: value larger than specified precision allowed for this column。
4. 浮点数表示
Oracle 也支持浮点形式的 NUMBER,但这通常不推荐用于需要精确计算的场景(如金额),因为浮点数存在精度损失的问题。
- 简单浮点数: 使用
BINARY_FLOAT和BINARY_DOUBLE类型,遵循 IEEE 754 标准,性能更高,但可能存在精度误差。 - NUMBER 的浮点表示法: 在定义时,可以用
NUMBER的变体来声明浮点数,但实践中较少使用。
5. 与其他数据库的对比
了解 NUMBER 与其他数据库数值类型的对应关系很有帮助:
| Oracle | MySQL / SQL Server | PostgreSQL | 注释 |
|---|---|---|---|
NUMBER | DECIMAL / NUMERIC | NUMERIC | 都是精确数值类型,语法和语义非常相似。 |
NUMBER(10) | INT | INTEGER | 用于存储整数。 |
NUMBER(10, 2) | DECIMAL(10, 2) | NUMERIC(10, 2) | 用于存储带小数的精确数值,如金额。 |
BINARY_FLOAT | FLOAT | REAL | 近似数值类型,存在精度损失,但性能好。 |
6. 最佳实践与使用建议
-
用于金额和精确计算:
NUMBER是存储货币金额、数量、利率等需要精确计算数据的首选。永远不要用FLOAT或BINARY_FLOAT来存金额。 -
合理设置精度和标度:
- 金额: 通常使用
NUMBER(19, 4)或NUMBER(18, 2)。(19,4)提供了非常大的整数范围(15位)和4位小数,足以满足全球绝大多数金融交易。 - 数量: 如商品件数,使用
NUMBER(10)或NUMBER(12)等整数形式即可。 - 比例/系数: 如税率、折扣率,可能需要较高的小数精度,例如
NUMBER(10, 6)。
- 金额: 通常使用
-
性能考虑:
NUMBER的运算和存储开销通常比BINARY_FLOAT/BINARY_DOUBLE或整数类型大。- 如果业务场景对性能要求极高且能接受微小的精度误差(如科学模拟),才考虑使用
BINARY_FLOAT。
-
避免不必要的精度定义:
除非有明确的业务规则限制,否则有时只使用NUMBER(不带参数)也是一种选择,因为它提供了最大的灵活性。但在企业级应用中,明确定义精度和标度是更好的做法,这可以作为数据有效性的第一道约束。
总结
| 特性 | 描述 |
|---|---|
| 类型 | 精确数值数据类型 |
| 存储内容 | 整数、定点小数、浮点数(不推荐) |
| 精度 (precision) | 1 到 38 (总有效位数) |
| 标度 (scale) | -84 到 127 (小数点后的位数,负值表示向左舍入) |
| 优点 | 高精度、无误差计算,非常适合金融等领域 |
| 缺点 | 相比浮点类型,计算和存储性能稍低 |
| 核心用途 | 金额、数量、费率等任何需要精确计算的业务数据 |
简单来说,当你需要在 Oracle 中存数字时,如果不确定用什么,首选 NUMBER,并根据业务规则为其指定合适的精度(precision)和标度(scale)。
6万+

被折叠的 条评论
为什么被折叠?



