DECIMAL 精度的定义与数据库上限
DECIMAL(p, s) 两个参数的含义
| 参数 | 名称 | 含义 | 例:DECIMAL(38,10) |
|---|---|---|---|
| p | Precision(精度) | 数值的总位数(整数部分 + 小数部分) | 共 38 位 |
| s | Scale(标度) | 小数点后保留的位数 | 小数点后 10 位 |
核心公式
整数部分位数 = p − s
DECIMAL(38,10)→ 整数部分 38 − 10 = 28 位
⚠️ 关键坑:p 有数据库上限
p 不是可以随意写大的,超出数据库上限会直接报”数据精度超出范围”:
| 数据库 | p 的上限 |
|---|---|
| 达梦(DM) | 38 |
| Oracle | 38 |
| MySQL | 65 |
| SQL Server | 38 |
-- ❌ 达梦报错:p = 50 超出上限 38
CREATE TABLE t (amount DECIMAL(50, 5));
-- ✅ 改为 38,整数部分仍有 33 位,绝大多数 ERP 场景够用
CREATE TABLE t (amount DECIMAL(38, 5));从其他数据库迁移到达梦时必查
MySQL 上能正常建表的
DECIMAL(50,5),迁到达梦会直接失败。这是数据库方言差异,不是数据问题。
常见定义与适用场景
| 定义 | 整数部分 | 小数部分 | 典型用途 |
|---|---|---|---|
DECIMAL(10,2) | 8 位 | 2 位 | 金额(元/分) |
DECIMAL(18,6) | 12 位 | 6 位 | 数量 / 单价 |
DECIMAL(38,5) | 33 位 | 5 位 | 大额汇总 |
DECIMAL(38,10) | 28 位 | 10 位 | 科学计算、高精度汇总 |
DECIMAL(38,0) | 38 位 | 0 位 | 纯整数 |
DECIMAL(10) | 10 位 | 0 位 | 等价于 DECIMAL(10,0) |
写入时的两种行为
-- ① 小数部分超出 s → 四舍五入(不报错,静默改值)
-- DECIMAL(10,2) 插入 123.4567
INSERT INTO t VALUES (123.4567);
-- 实际存储: 123.46
-- ② 整数部分超出 p−s → 报错
-- DECIMAL(10,2) 只能存 8 位整数,插 100000000
-- 报错:数据精度超出范围静默四舍五入是金额场景的隐患
场景①不报错、只悄悄改值。金额字段若用
DECIMAL(10,2)承接更高精度的小数,误差会静默累积,务必在应用层明确舍入规则。
参考链接
- SQL-in和not-in的NULL陷阱 — 同为 SQL 静默语义陷阱