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

相关推荐
计算机毕设VX:Fegn08952 分钟前
计算机毕业设计|基于springboot + vue图书借阅管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
疯狂的程序猴9 分钟前
IPA 深度混淆是什么意思?分析其与普通混淆的区别
后端
cci11 分钟前
Remote ssh无法连接?
后端
JohnYan21 分钟前
Bun技术评估 - 22 Stream
javascript·后端·bun
okseekw33 分钟前
Maven从入门到实战:核心概念+配置详解+避坑指南
java·后端
该用户已不存在34 分钟前
Node.js后端开发必不可少的7个核心库
javascript·后端·node.js
踏浪无痕35 分钟前
计算机算钱为什么会算错?怎么解决?
后端·算法·面试
undsky_36 分钟前
【RuoYi-SpringBoot3-Pro】:接入 AI 对话能力
人工智能·spring boot·后端·ai·ruoyi
疯狂的程序猴37 分钟前
一次 iOS App 日志排查的真实经历,测试的时候如何查看实时日志
后端
墨守城规39 分钟前
ThreadLocal深入刨析
后端