上一篇
场景引入:
小明最近在开发一个电商财务系统,遇到一个头疼的问题——商品价格计算时总出现"0.1 + 0.2 ≠ 0.3"的诡异现象 😱,原来,系统用浮点数存储金额导致精度丢失!这时,数据库老司机老王拍了拍他:"试试MySQL的Decimal类型?"
-- 用FLOAT类型计算会翻车! SELECT 0.1 + 0.2; -- 结果可能是0.30000000000000004 🤯
💡 核心问题:计算机用二进制存储浮点数,像0.1这样的十进制数无法精确表示,就像1/3在十进制中无法精确表示一样。
✅ 金融交易(金额计算)
✅ 科学测量(需要固定精度)
✅ 统计报表(数据汇总)
DECIMAL(M, D) -- M是总位数(1~65),D是小数位数 -- DECIMAL(5,2) 能存 -999.99 到 999.99
CREATE TABLE products ( id INT, price DECIMAL(10, 2) -- 十亿级金额,精确到分 ); INSERT INTO products VALUES (1, 399.99); INSERT INTO products VALUES (2, 0.01);
-- 完美计算! SELECT 0.1 + 0.2; -- 0.3(需先转Decimal) SELECT CAST(0.1 AS DECIMAL) + 0.2; -- 0.3 👍
-- 混合运算时要注意类型! SELECT price * 1.1 FROM products; -- 1.1是浮点数,可能丢失精度 SELECT price * CAST(1.1 AS DECIMAL) FROM products; -- 安全做法
⚡ 存储空间:
💡 设计技巧:
-- 根据业务合理设置精度 DECIMAL(10,2) -- 适合金额(精确到分) DECIMAL(7,4) -- 适合温度记录(-999.9999~999.9999)
类型 | 精度 | 存储空间 | 适用场景 |
---|---|---|---|
FLOAT | 约7位有效数字 | 4字节 | 科学计算 |
DOUBLE | 约15位有效数字 | 8字节 | 普通工程计算 |
DECIMAL | 精确计算 | 变长 | 财务/统计 |
旧方案(问题代码):
ALTER TABLE orders MODIFY total_amount FLOAT; -- 错误示范!
新方案(精确方案):
-- 1. 修改表结构 ALTER TABLE orders MODIFY total_amount DECIMAL(12,2); -- 2. 计算订单总价(精确到分) UPDATE orders SET total_amount = ( SELECT SUM(price * quantity) FROM order_items WHERE order_id = orders.id );
❓ Q:Decimal会降低性能吗?
👉 确实比浮点数稍慢,但金融系统优先保证正确性!可以通过分库分表缓解压力。
❓ Q:超出精度范围会怎样?
👉 MySQL会按以下规则处理:
❓ Q:Java程序如何对应Decimal?
👉 推荐使用BigDecimal
类型对接,绝对不要用double
!
记住老王的口头禅:"金额计算用Decimal,浮点误差毁前程!" 💸 下次遇到需要精确计算的场景,别再被浮点数坑啦~
(本文技术要点验证于MySQL 8.0.28版本,2025-08最新测试通过)
本文由 狂玉宸 于2025-08-03发表在【云服务器提供商】,文中图片由(狂玉宸)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/525335.html
发表评论