一次 MySQL IF 函数的误用导致的生产小事故

事件起因

这起生产小事故其实还是七月份的事情,本来早就准备写篇博客记录下,但由于各种原因拖到了现在才写,附上当时的提交记录:

简要的来说就是有两张表,一张资源表,一张资源收藏表,每个用户收藏了某个资源就会在资源收藏中进行记录,如果取消收藏,则从收藏表进行删除。在开发阶段该功能一切正常,但是生产环境会出现收藏后在表中添加了记录,但是界面是始终展示的未收藏的效果,同时多次点收藏都会在表中添加记录,但是界面上始终显示的是未收藏。由于该功能是直接从以往项目代码中复制而来,当现场实施人员反馈这个问题时,几个同事也都在本地进行了测试并且功能一切正常,但都没有发现代码有什么问题,问题一时陷入僵局。。。

发现问题

在排查的过程中我发现该功能的查询直接是使用原生 SQL 进行查询,并且页面中展示是否收藏是通过if(resource_id,'1','0') isFavorite(resource_id 是资源收藏表中的字段)来查询资源是否已在收藏表中存在。然后我就先调试代码再将执行的SQL复制直接执行,但都没发现问题,返回结果也一切正常。这时我就想会不会是现场数据或者配置有什么问题,因此我就将执行的 SQL 直接进行了执行,结果收藏表中有数据,isFavorite字段却还是 0,思索了一会,我就在查询字段中直接添加了resource_id字段,这是发现查询结果中resource_id字段有值,isFavorite却为 0。然后我就把查询得到的resource_id直接带入了if(resource_id,'1','0'),结果竟然真的是0,我一时有些懵逼。又过了一会,我决定还是先看一下开发库,并在开发库中重复了上述的步骤,然后不知过了多久(由于已经过去将近半年,我也不记得具体是如何发现以及用了多久),我突然发现开发库的 id 字段都是4开头的UUID字符串格式,生产环境则是f开头的UUID字符串。并且在执行SQL的时候,控制台还出现了类似Truncated incorrect DOUBLE value: 'f12a836542956397'的警告,然后经过查询发现MySQL在计算表达式的时候的确会将字符串转为浮点类型,并且只会从前到后截取字符串中的数字进行转换,这也是上述警告出现的原因。这时我也终于知道了问题的所在,直接将上述的SQL语句改为if(resource_id is not null,'1','0')即可,当然这里改为使用ifnull函数或者直接查询resource_id的值,然后通过代码判断再设置字段也是可以的。

问题总结

总的来说,这个小问题还是对基础掌握不够牢,代码编写不规范导致的。不过,就我个人来说,除非不得已,我不太喜欢在 SQL 中写太多逻辑(记不住那么多SQL语法哈哈,当然随着GPT的出现,让AI去写还是很方便的),还是喜欢在代码中处理。以上就是对这次小事故的一个总结,文中结论如有错误之处,也欢迎在评论区交流讨论。

题外话

如果不是因为这次生产环境生成的UUID 是非非数字开头,还不知道这个 bug 会隐藏多久😂

相关推荐
消失的旧时光-194321 分钟前
Spring Boot 工程化进阶:统一返回 + 全局异常 + AOP 通用工具包
java·spring boot·后端·aop·自定义注解
追风筝的人er1 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端
金銀銅鐵2 小时前
[git] 如何丢弃对一个文件的改动?
git·后端
橘子海全栈攻城狮2 小时前
【最新源码】养老院系统管理A013
java·spring boot·后端·web安全·微信小程序
smallyoung3 小时前
具有反思能力的 Agentic RAG 实战:用 LangChain4j 实现 CRAG 纠错检索
人工智能·后端
EthanYuan3 小时前
💡RAG实践:从云知识库迁移到PostgreSQL ,并使用PGVector实现向量存储
后端
直奔標竿3 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
等风来_shy3 小时前
如何写好一个 Skill
后端
ailab4 小时前
研发人员如何写好 AI 提示词:从“问问题”到“驱动研发闭环”
后端
ltl4 小时前
【大模型基础设施工程】25:大模型基础设施未来
后端