IS NULL 是唯一安全的空值判断方式,因 NULL 是缺失标记而非值,= NULL 永返 NULL;需区分 NULL、空字符串、零值及空格;WHERE 中高效,JOIN 和复合索引中需谨慎;COALESCE 等函数可归一化但可能失效索引。

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 解决不了所有“空”。










