MySQL中不能用= NULL判断空值,必须用IS NULL,因为NULL是未知状态,所有等值比较均返回UNKNOWN,而WHERE只保留TRUE结果;IS NULL可走索引,但受联合索引顺序和NOT NULL约束影响;NULL与''语义不同,需按业务上下文准确理解。

MySQL 中不能用 = NULL 判断空值,必须用 IS NULL —— 因为 NULL 在 SQL 中不是值,而是“未知”状态,所有与 NULL 的等值比较(包括 =、!=、<>)都返回 UNKNOWN,而非 TRUE 或 FALSE。
为什么 = NULL 永远不生效
SQL 标准规定:任何值(包括 NULL 自身)与 NULL 做 = 比较,结果都不是布尔真/假,而是三值逻辑中的 UNKNOWN。而 WHERE 子句只保留结果为 TRUE 的行,UNKNOWN 被当作“不满足”,直接过滤掉。
常见错误现象:
- 执行
SELECT * FROM user WHERE name = NULL返回空结果,即使表中明明有name为 NULL 的记录 - 用
name != 'Alice'也查不到name为 NULL 的行 —— 因为NULL != 'Alice'同样是UNKNOWN
IS NULL 和 IS NOT NULL 是唯一可靠方式
这两个是专门设计用于判断 NULL 的谓词,返回确定的布尔值,不受三值逻辑干扰。
使用场景:
- 筛选缺失数据:
SELECT * FROM order WHERE shipped_at IS NULL - 补全默认值前校验:
UPDATE product SET price = 99 WHERE price IS NULL - 在
JOIN条件中安全匹配:ON a.user_id = b.id OR (a.user_id IS NULL AND b.id IS NULL)(慎用,通常应避免 NULL 参与 JOIN)
注意 IS NULL 无法走索引?不一定
很多人误以为 IS NULL 一定无法利用索引,其实取决于存储引擎和索引类型:
- InnoDB 支持对包含 NULL 的列建立 B+ 树索引,
IS NULL可以命中索引(前提是该列在索引中且非最左前缀被跳过) - 但
IS NULL在联合索引中若非最左字段,或前面有范围查询(如WHERE a > 10 AND b IS NULL),可能无法用到b部分的索引 - 如果列定义为
NOT NULL,那IS NULL条件永远为假,优化器会直接剪枝 —— 所以建表时尽量明确是否允许 NULL
别混淆 IS NULL 和空字符串 ''
这是新手高频踩坑点:NULL 和 '' 完全不同,前者是“无值”,后者是“有值,值为空字符串”。
实操建议:
- 检查字段是否真的为 NULL:
SELECT * FROM user WHERE phone IS NULL - 检查是否为空字符串:
SELECT * FROM user WHERE phone = '' - 同时覆盖两种情况:
SELECT * FROM user WHERE phone IS NULL OR phone = '' - 更严谨的做法是统一清洗:插入前用
NULLIF(phone, '')把空字符串转成 NULL,或用COALESCE(phone, 'N/A')查询时兜底
真正容易被忽略的是:NULL 的语义由业务决定,不是技术问题。比如 updated_at IS NULL 可能表示“从未更新”,也可能表示“更新时间未采集”——同一字段在不同表里含义可能不同,写条件前先确认业务上下文比记住语法更重要。


















