MySQL中decimal类型

工资、订单金额和税率等字段,如果要求按十进制精确保留数值,通常会考虑 DECIMAL。MySQL 中 NUMERIC 作为 DECIMAL 实现,可以按相同类型理解。

一、精度与小数位数

salary DECIMAL(9, 2)

9 是精度(precision),表示整数部分和小数部分合计的十进制数字位数;2 是标度(scale),表示小数点后的位数。符号和小数点不计入这 9 位。

因此整数部分最多 7 位,有符号值的范围为 -9999999.99 到 9999999.99。

amount DECIMAL(6, 2) -- 范围:-9999.99 到 9999.99

按 MySQL 8.4 的规则,精度最大 65,标度最大 30,且不能超过精度;省略标度时默认 0,连精度也省略时默认为 DECIMAL(10,0)。字段规格应按业务上限、币种和中间计算的需要确定,不必给所有金额都套同一组参数。

二、DECIMAL 不是直接按字符串存储

当前 MySQL 使用二进制格式编码 DECIMAL 的精确数值,并不是将文本 123.45 原样保存为字符串。驱动把查询结果返回为字符串,通常是应用接口为避免精度损失而做的选择,不能据此推断数据库的内部存储格式。

FLOAT、DOUBLE 的问题也不是“使用二进制存储”本身,而是二进制浮点表示无法精确表达许多有限十进制小数。DECIMAL 的数值编码和运算规则与它们不同。参考 MySQL DECIMAL、NUMERIC 文档。

三、数据库类型正确,应用链路也要配合

PHP 中可以从规范的十进制字符串传入金额,由数据库驱动绑定参数,避免先转成 float 再写回。读出后如果仍要精确计算,也应使用 BCMath 等合适的计算方式。

输入的十进制字符串 → 参数绑定 → DECIMAL 列
DECIMAL 查询结果 → 精确计算 → 按业务规则展示

超过字段小数位的输入可能发生舍入;超出范围的处理还与 SQL 模式等有关。字段类型不能替你决定税费、折扣和尾差如何处理,这些规则需要明确约定。

相关笔记:PHP 浮点数格式化与舍入、PHP JSON 与浮点数精度。


文章作者: Crazy Boy
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Crazy Boy !
赏

留言

想法、疑问或勘误,都可以写在这里。留言会公开显示。

正在准备留言区…

 上一篇
详解php.ini 详解php.ini
safe_mode_exec_dir 设置安全模式下脚本可执行的目录,如果要通过popen()、system()、exec()等执行脚本,则该脚本需放在本配置设置的目录下。
2020-07-12
下一篇 
MySQL中的explain MySQL中的explain
当我们在执行sql时,一般都会使用explain来分析sql的效率情况。 用法 只需要在查询的 SQL 前面添加上 explain 关键字即可。 结果列说明 id — 选择标识符,id 越大优先级越高,越先被执行; select_type
2020-06-12