线上问题:MySQL NULL值引发的投诉

一、前言

2025.08.07 线上收到测试同学反馈,几个商机客户在商机公海里搜索不到,需要协助查看。

一开始以为是对应销售同学没有配置好对应池,所以才搜索不到。

销管明确说已正确配置池,并提供搜索不到商机客户的 clientId。测试同学和产品同同学也一起尝试了,发现确实搜索不到。

反馈到我这,让帮忙排查下。

通过接口开始排查:

  1. 加密搜索是否有问题:邮箱搜索是先加密再搜索
  2. 查询 SQL 是否有问题:字段问题

发现有 userStatus 字段,使用 NOT IN 查询。

在线上使用相同 SQL,加上 userStatus not in ('Unbind','Blocked')确实搜索不到。

且对应 clientId 中 userStatus 的值是 NULL。

那就是这块有问题,正常客户的 userStatus 不能为 NULL。

且在 MySQL / ADB 中,当 userStatus 字段为 null 时,使用 NOT IN 搜索不到。

这是因为在 SQL 中,任何与 NULL 的比较操作(包括 INNOT IN)都会返回 NULL(未知),而不是 TRUEFALSE。在 WHERE 子句中,只有返回 TRUE 的记录才会被包含在结果集中。

修正方法:

  1. 线上数据订正:将对应的数据的 userStatus 改为正常值
  2. 修改查询 SQL:支持 userStatus 为 NULL,SQL 如下
sql 复制代码
SELECT * FROM customer 
    WHERE clientId = '123'AND (ownerId IS NULL OR ownerId = '')  AND (userStatus IS NULL OR userStatus NOT IN ('Unbind','Blocked'))

Hotfix:找到原因,跟当时开发同学沟通并确定,让其先补数据,并让其事后TODO修复。

PS:这块是工作了8年的前阿里同学写的。基础不扎实,小问题也会放大。

二、小结

为什么很多人建议 MySQL 字段不要设置为 NULL

主要原因并不是说 NULL 一定不好,而是它在实际使用中会带来一些性能、语义和维护上的问题。

  1. NULL 的语义复杂:在 SQL 中,NULL 表示"未知"或"不存在",它不是 0、空字符串、false,也不是任何具体值。

    sql 复制代码
    -- 这意味着在比较时,NULL 有特殊规则:
    SELECT * FROM customer WHERE userStatus = NULL; -- 永远返回空结果
    SELECT * FROM customer WHERE userStatus IS NULL; -- 才能判断是否为 NULL
    
    -- 如果开发人员不熟悉这些规则,很容易写出错误的查询。
  2. 索引和性能问题:在 MySQL(尤其是 InnoDB)中,NULL 值会影响索引存储方式。

    1. 对含有 NULL 的列建立索引时,MySQL 会额外存储一个标志位来表示该值是否为 NULL,这会增加索引空间占用。
    2. 某些情况下,NULL 会让索引选择性降低,影响查询优化器的执行计划。
  3. 聚合和统计的复杂性:COUNT(column) 不会统计 NULL 值,而 COUNT(*) 会统计所有行。

    sql 复制代码
    SELECT COUNT(status) FROM customer; -- 不统计 status 为 NULL 的行
    SELECT COUNT(*) FROM customer;      -- 统计所有行
  4. 存储上的差异:NULL 列会额外占用 1 bit 的空间来记录是否为 NULL

Tips:好的编程习惯可以避免很多低级错误。

Java 开发者都需要学习:《阿里巴巴Java开发规范》

相关推荐
冰暮流星1 分钟前
mysql之排序查询
数据库·mysql
长栎21 分钟前
你的 AI 品控规则越来越多了——但它们已经在打架了,你没看见
后端
有脚就行24 分钟前
第24篇-Go-gRPC推理服务-高性能跨语言通信
开发语言·人工智能·后端·golang
不好听61327 分钟前
NestJS 是什么?一张图看懂企业级后端的骨架
后端·nestjs
liuxiaocheng30 分钟前
文本生成的进阶:generateText / streamText 里迟早会撞上的东西
前端·后端·ai编程
江小渔41 分钟前
训练工程与训练平台入门33 追踪一次 TrainJob 的完整生命周期
后端
无糖可可果44 分钟前
NestJS 学习分享:从工厂模式到企业级后端开发
后端
vipbic1 小时前
网站升级了,我却有点舍不得
前端·vue.js·后端
IT_陈寒1 小时前
Java Stream并行处理让我数据库崩了两次
前端·人工智能·后端
2601_963870221 小时前
【计算机毕业设计】基于Spring Boot的考研信息交流平台的设计与实现
java·spring boot·后端