⏰周统计少一周?这个坑太隐蔽

5 阅读5分钟

大家好,这里是EthanYuan。今天跟大家聊聊我当时开发昴云相册时,踩过的两个超坑的统计 BUG,折腾了我好半天,最后发现问题都出在细节上,却直接影响了整个相册分析功能的准确性。

背景和思考

做云相册平台,核心功能之一就是上传趋势分析 —— 管理员想按日、周、月看图片上传量,还能切换公共图库、全相册、指定相册不同维度看数据。本来以为就是简单的SQL 分组统计 + 前端展示,结果上线后一核对数据,直接傻了眼:周维度的统计前后对不上,全相册的统计数据莫名偏大,上传趋势完全是错的,体验直接拉胯。

我当时排查了半天,从前端日期组件查到后端 SQL 函数,从数据筛选条件查到字段含义,终于揪出了两个根因,今天就把这两个 BUG 的来龙去脉、踩坑过程和解决方案全分享给大家,避免各位以后踩同样的坑。

坑点1:ISO 周统计标准不统一,前后端差一周

最先发现的问题是周统计数据前后端偏差,前端展示的周数,永远比后端实际统计的结果少一周,尤其是跨年份的日期,偏差特别明显。

我一开始以为是前端日期格式化错了,改了好几版解析逻辑都没用,后来扒后端统计 SQL 才发现问题:

后端用 MySQL 的yearweek函数做周维度统计,特意用了模式参数 3,这是 ISO8601 国际标准 —— 规定每周从周一开始,而且一年的第一周必须包含当年第一个周四。

这个标准看着规范,却藏了个大坑:跨年的边界日期,会被归入不同的周年份里。比如 2023 年最后几天,可能会被算成 2024 年的第一周。

结果前端完全没适配这个标准,用的是普通周计算逻辑,要么周日当一周开始,要么单纯七天算一周,根本没按 ISO8601 解析后端返回的周期。后端算的是标准周,前端按普通周展示,两边口径完全不一样,周数偏差就这么来了。

解决方案也很简单:要么前端改解析逻辑,完全适配 ISO8601 标准,正确识别后端的周年份格式;要么后端换周计算模式,改成和普通日历一致的口径。我最后选择了前后端统一 ISO 标准,毕竟国际规范更稳妥,改完前端解析,周统计立马对齐了。

第二个坑:少加一个非空判断,全相册统计混进公共数据

解决完周统计的问题,又发现全相册上传统计数据范围错误,数据比实际偏大很多,对比公共图库的统计结果,怎么算都对不上。

我逐行核对统计 SQL 的筛选条件,终于发现致命问题:全相册月度上传统计,漏掉了空间 ID 非空的过滤条件

这里给大家科普下昴云相册的数据逻辑:公共图库的图片记录,空间 ID 字段是空值;用户私有相册的图片,空间 ID 都有具体值。管理员点「全相册统计」,本意是看所有私有相册的汇总数据,结果因为没加空间 ID 非空判断,SQL 把公共图库的图片也一起统计进去了,数据能不大吗?

更有意思的是,公共图库的统计是完全正确的,因为开发时特意加了空间 ID 为空的筛选条件,偏偏全相册统计忘了加反向限制,导致数据串了。

修复方案超简单:在全相册统计的查询条件里,补上spaceId IS NOT NULL,直接把公共图库和私有相册的数据彻底隔离,统计结果瞬间精准了。


这两个问题,全都出在相册分析功能模块,一个影响时间维度的展示一致性,一个影响数据范围的精确性,看似都是小细节,却直接毁了整个统计功能的可用性。

修复完这两个 BUG 后,云相册的上传趋势分析终于靠谱了:不管是按日、周、月查看,还是切换公共图库、全相册、指定相册,数据都准确无误,前后端也完全对齐。

其实做开发,尤其是涉及数据统计的功能,最容易栽在「标准不统一」「筛选条件不严谨」这种小问题上。写 SQL、做前后端联调时,多核对一遍口径、多检查一个条件,能少走无数弯路。

今天的踩坑分享就到这,希望大家以后开发数据类功能时,都能避开这些坑!

总结

  1. 数据统计务必保证前后端口径绝对统一,日期、周、月这种时间维度,一定要明确用不用国际标准,别各算各的;
  2. 多维度数据统计,筛选条件必须严谨,关联字段的空值判断千万不能漏,不然很容易混入无关数据;
  3. 涉及用户核心感知的数据功能,上线前一定要多维度、跨边界测试(比如跨年日期、不同数据类型),别让小细节毁了体验。