
最近排查一个 PHP 后台时遇到过这种情况:页面按"金额从大到小"排序,结果却出现了 99 排在 1000 前面、800 排在 90 后面的情况。PHP 接口没有报错,SQL 里的 ORDER BY amount DESC 也写得没问题。
继续看表结构后才发现,amount 字段当初为了兼容导入数据,被定义成了 VARCHAR。
MySQL 对字符串排序时比较的是字符顺序,而不是数值大小。比如 "99" 和 "1000" 比较时,会先比较第一个字符,9 自然会排在 1 前面,所以结果看起来就像"排序失效"。
临时处理可以在 SQL 里使用 CAST(amount AS DECIMAL) 转成数值后再排序,但这样做在数据量大时可能影响索引使用,查询性能也会下降。
后来把数据先清洗一遍,将金额字段正式改成 DECIMAL 类型。像数量、金额、重量、积分这类需要计算和排序的数据,也统一按照实际用途设计字段类型,不再为了"方便存任何内容"全部使用字符串。
现在遇到排序结果异常,我一般除了检查 ORDER BY,还会先确认字段类型。
数据库字段能存进去,并不代表类型设计就是合理的。很多查询、统计和索引问题,最后都和最开始的字段类型选择有关。
#PHP开发 #MySQL #数据库设计 #数据排序