线上问题: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开发规范》

相关推荐
dessler1 小时前
MYSQL-物理备份(xtrabackup)使用指南
linux·数据库·mysql
5***26201 小时前
MySQL存储过程优化实例
数据库·mysql
Moe4881 小时前
Spring Boot 自动配置核心:AutoConfigurationImportSelector 深度解析
java·后端·设计模式
Anthony_49261 小时前
【踩坑】gorm 回写主键不正确
mysql·go·orm
武子康1 小时前
大数据-161 Apache Kylin Cube 实战:建模、构建与查询加速完整指南
大数据·后端·apache kylin
踏浪无痕1 小时前
准备手写Simple Raft(三) 日志复制——一致性检查
后端·raft
星轨初途1 小时前
数据结构二叉树之链式结构(3)(下)
c语言·网络·数据结构·经验分享·笔记·后端
q_19132846952 小时前
基于SpringBoot2+Vue2的宠物健康医疗论坛系统
vue.js·spring boot·mysql·健康医疗·宠物·计算机毕业设计
yuuki2332332 小时前
【C语言&数据结构】二叉树的链式递归
c语言·数据结构·后端