前言
今天一个很久前做的项目突然找到我,说是之前做的项目中,页面上数据汇总和列表中的数据的总数存在对不上的问题。说是列表是对的,但是根据列表统计出来的数据要比正常小很多。
排查
这个项目已经好几年了,之前用了很久都是正常的,不可能会突然出问题了;我觉得这个统计肯定是没问题了,很大可能就是统计是对的,但是导入的数据不对。
第一步,我浏览一遍这个功能的源码,找到统计和列表的执行的SQL语句,查询在数据中查询,手动使用sum函数再计算一下,发现和页面上统计出来的是一致的,这个时候我强烈怀疑是不是他算错了就是这个,这个时候我也注意到,列表查询的数据行数和导入数据的行数不一致,询问后那边回复,有少数数据为0,导入后手动删除了。至此,没有找到具体的问题。
第二步,将列表中的数据导出为Excel文件,使用Excel求和,结果发现这个数据是对的;我都开始怀疑是不是Excel的求和计算有什么问题;发现两边计算不多时,我就将这一列的数据复制到vscode中,写了一个python将一列放到List中,使用sum(list) 计算,因为数据行有几百上千,我不可能一个个删除换行符,手动插入逗号,所以我是将换行符直接替换为逗号,结果发现计算出来的值,既和Excel计算的不一致,也和mysql sum函数计算的不一致,我就在打印了一行list的数据,发现比数据行多了几个;我当时还怀疑是不是复制的时候不小心多,我就有重新复制了一份,就上下滚动看一了一行,发现里面超过千的数据都有一个分隔符,突然我就想到会不会分隔符的问题,手动删除了,在重新计算了一遍,发现数据是对的,至此,问题已经找到,就是导入数据时,数字中包含分隔符,所以计算有问题。树洞修改数据库中带分隔符的数据,数据正常。
结论
排查问题时,还是犯了惯性思维的错误,总觉得这么久的功能不可能是有问题的。最后发现确实bug导致。
导致这个问题出现的原因是,数据库设计时,数字字段使用了varchat字段,导入数据时没有判断是否为数字。其次是mysql数据在字符串做计算时,会自动将字符串转化为数字,但是如果文本不为数字时,会从前往后提取数字,一旦碰到非数字的就直接忽略后续所有的字符。
以下为转化数字文本的具体事例: