MySQL 中 IS NULL
是唯一安全的空值判断方式
MySQL 的
NULL不是值,而是“缺失值”的标记,所以不能用
= NULL或
!= NULL判断——这些表达式永远返回
NULL(即逻辑假),导致查询结果为空或不符合预期。必须用
IS NULL和
IS NOT NULL。
SELECT * FROM users WHERE name = NULL;→ 查不到任何记录,哪怕 name 真的是 NULL
SELECT * FROM users WHERE name IS NULL;→ 正确写法,能命中所有 name 为 NULL 的行 注意:字符串
''(空字符串)和
NULL完全不同,
IS NULL对空字符串无效
区分 NULL
、空字符串和零值的常见陷阱
尤其在用户输入字段(如
phone、
address)中,可能混入
NULL、
''、
' '(带空格)、甚至数字
0。仅靠
IS NULL无法覆盖全部“空”语义。 查真正意义上的“未填写”:用
column IS NULL查“填了但留空”:用
TRIM(column) = ''(注意
TRIM会把 NULL 转成 NULL,所以需配合
OR column IS NULL) 查“数值型字段为 0 或 NULL”:用
num_col IS NULL OR num_col = 0,不能写成
COALESCE(num_col, 0) = 0(会误判原本就是 0 的有效数据)
在 WHERE
、JOIN
和索引中的行为差异
IS NULL在不同上下文表现不一致,容易引发性能或逻辑问题。
WHERE中可用且高效:如果字段有索引,
IS NULL可走索引(前提是该索引允许 NULL,比如非唯一索引或明确声明
ALLOW NULL)
JOIN条件中慎用:
ON a.id = b.user_id OR b.user_id IS NULL这类写法会导致笛卡尔积倾向,应优先重构为
LEFT JOIN+ 后置过滤 复合索引中 NULL 的位置影响匹配:例如索引
(status, created_at),
WHERE status IS NULL可用索引,但
WHERE created_at IS NULL通常不可用(因前导列
status未指定确定值)
替代方案:用 COALESCE
或 IFNULL
统一空值语义
当业务上把
NULL、空字符串都视作“空”,又不想写冗长的
OR条件时,可借助函数归一化,但要注意副作用。
WHERE COALESCE(phone, '') = ''→ 把 NULL 转成
''再比,覆盖两种情况
WHERE IFNULL(email, 'missing') = 'missing'→ 更明确地设默认值 ⚠️ 注意:这类写法会让字段失去索引能力,除非你建了函数索引(MySQL 8.0.13+ 支持
CREATE INDEX idx ON t ((COALESCE(col, ''))))
实际写查询时,先想清楚你要的“空”到底指什么:数据库层面的缺失(
IS NULL),还是业务层面的无效(需结合
TRIM、
= ''、
LENGTH = 0等)。一个
IS NULL解决不了所有“空”。
