月底对账,订单金额加起来差了三分钱,查到最后是金额字段用了 float。二进制浮点存不下 0.1 这种十进制小数,累积起来就会飘。

float 存的是近似值,0.1 在二进制里是无限循环小数,只能截断保存。单条记录看不出差别,几万条一起求和,误差就露出来了。金额这种要一分不差的数据,得用 decimal。

DECIMAL(10,2) 到底能存多大

括号里第一个数 10 是总位数,第二个数 2 是小数位,整数部分只剩 8 位,最大值 99999999.99。金额字段常用 DECIMAL(10,2) 或者 DECIMAL(12,2),按业务上限留够余量。不写括号时默认是 DECIMAL(10,0),小数位为 0,存 9.9 会变成 10。

超范围会报 1264

严格模式下插入超范围的数字,MySQL 直接抛 Out of range value for column,错误号 1264,语句被拒绝。非严格模式只给个警告,值被截成边界值,这种静默截断最坑,线上一般还是开着严格模式。插入前用程序校验一下位数,比等数据库报错更主动。

建表和改表的写法

建表时写 amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,改字段用 ALTER TABLE orders MODIFY amount DECIMAL(12,2)。改大一般没问题,改小要小心,已有数据超出新范围会直接报错。字段名别用 decimal 当列名,跟类型重名,写 SQL 时容易看花眼。

float 什么时候还该用

float 和 double 是二进制浮点,速度快、占空间小,适合传感器读数、科学计算这类本来就有误差的场景。decimal 按十进制存,精度不丢,代价是运算慢一点、占空间多一点。一张业务表里金额字段就那么几个,这点开销可以接受。已经建好的表改类型前先备份,float 里的 19.99 转成 decimal 会变成多少,得拿真实数据试一遍。

判断标准很简单:字段跟钱、税率、单价有关,用 DECIMAL;只做统计图表、允许误差,float 也能凑合。mysql decimal 的取舍就这一条,别为了省几个字节把账算错。