MYSQL——基础知识(NULL 值处理)

前言

[一、什么是 NULL?](#一、什么是 NULL?)

[二、为什么 = NULL 不起作用?](#二、为什么 = NULL 不起作用?)

[三、MySQL 处理 NULL 的三大核心工具](#三、MySQL 处理 NULL 的三大核心工具)

[四、NULL 在聚合函数中的行为](#四、NULL 在聚合函数中的行为)

[五、NULL 在排序中的表现](#五、NULL 在排序中的表现)

[六、PHP 脚本中处理 NULL](#六、PHP 脚本中处理 NULL)

[七、设计建议:何时允许 NULL?](#七、设计建议:何时允许 NULL?)

小结


前言

在 MySQL 数据库开发中,NULL 是一个特殊且容易被误解的值。它不代表"空字符串"或"0",而是表示缺失、未知或不适用的数据。许多开发者因对 NULL 的处理不当,导致查询结果不符合预期,甚至引发逻辑错误。本文将系统讲解 MySQL 中 NULL 的特性、常见误区以及正确处理方法。


一、什么是 NULL?

  • NULL ≠ 空字符串('')
  • NULL ≠ 数字 0
  • NULL 表示"没有值"或"值未知"

例如:

  • 用户未填写电话号码 → phone = NULL
  • 商品尚未定价 → price = NULL
  • 员工尚未分配部门 → department_id = NULL

注意:
任何与 NULL 的比较(包括 = NULL!= NULL< NULL 等)结果都是 UNKNOWN(在布尔上下文中视为 FALSE


二、为什么 = NULL 不起作用?

这是最常见的误区!

sql 复制代码
-- 错误写法:永远返回空结果集
SELECT * FROM yuming_test_tbl WHERE yuming_count = NULL;

-- 同样无效
SELECT * FROM yuming_test_tbl WHERE yuming_count != NULL;

原因分析:

在 SQL 三值逻辑中,NULL = NULL 的结果是 NULL(未知) ,而非 TRUE。因此,WHERE 子句不会将其视为匹配条件。

正确做法 :使用专用运算符 IS NULLIS NOT NULL

sql 复制代码
-- 查找 NULL 值
SELECT * FROM yuming_test_tbl WHERE yuming_count IS NULL;

-- 查找非 NULL 值
SELECT * FROM yuming_test_tbl WHERE yuming_count IS NOT NULL;

三、MySQL 处理 NULL 的三大核心工具

1. IS NULL / IS NOT NULL ------ 判断是否为 NULL

用于 WHEREHAVING 等条件判断。

sql 复制代码
-- 示例:找出未分配部门的员工
SELECT name FROM employees WHERE department_id IS NULL;

-- 示例:统计有薪资记录的员工数
SELECT COUNT(*) FROM employees WHERE salary IS NOT NULL;

2. <=> 安全等于操作符(NULL-safe equality)

这是 MySQL 特有的NULL 安全比较符 ,即使两边都是 NULL,也返回 TRUE

表达式 结果
NULL <=> NULL 1(TRUE)
'A' <=> 'A' 1
'A' <=> NULL 0(FALSE)
5 <=> 5 1
sql 复制代码
-- 查找 commission 为 NULL 的员工(等价于 IS NULL)
SELECT * FROM employees WHERE commission <=> NULL;

-- 在 JOIN 中安全比较(避免因 NULL 导致漏连)
SELECT * FROM t1 JOIN t2 ON t1.id <=> t2.ref_id;

💡 适用于需要将 NULL 视为"相等"的场景,如数据比对、去重等。


3. 替换 NULL 值的函数

(1) IFNULL(expr1, expr2)
  • MySQL 特有;
  • expr1 为 NULL,返回 expr2;否则返回 expr1
sql 复制代码
-- 将 NULL 阅读量显示为 0
SELECT yuming_author, IFNULL(yuming_count, 0) AS views
FROM yuming_test_tbl;
(2) COALESCE(value1, value2, ..., valueN)
  • 标准 SQL 函数,兼容性更好;
  • 返回参数列表中第一个非 NULL 的值
sql 复制代码
-- 多级备用值:优先用手机,其次邮箱,最后"未提供"
SELECT name, COALESCE(phone, email, '未提供') AS contact
FROM users;

在跨数据库项目中优先使用 COALESCE


四、NULL 在聚合函数中的行为

大多数聚合函数会自动忽略 NULL 值

函数 对 NULL 的处理
COUNT(*) 统计所有行(含 NULL)
COUNT(column) 仅统计非 NULL 行
SUM(), AVG(), MAX(), MIN() 忽略 NULL
sql 复制代码
-- 示例表:salaries = [1000, 2000, NULL, 3000]

SELECT COUNT(*)        -- 结果: 4(总行数)
SELECT COUNT(salary)   -- 结果: 3(非 NULL 行数)
SELECT AVG(salary)     -- 结果: 2000((1000+2000+3000)/3)

若希望将 NULL 视为 0 参与计算:

sql 复制代码
-- 计算平均薪资(NULL 视为 0)
SELECT AVG(IFNULL(salary, 0)) AS avg_salary FROM employees;

五、NULL 在排序中的表现

默认情况下:

  • 升序(ASC):NULL 排在最前(MySQL 8.0+ 可控);
  • 降序(DESC):NULL 排在最后。

但可通过 NULLS FIRST / NULLS LAST 显式控制(MySQL 8.0.16+):

sql 复制代码
-- 将 NULL 价格排在最后
SELECT product_name, price
FROM products
ORDER BY price ASC NULLS LAST;

-- 将 NULL 日期排在最前
SELECT title, publish_date
FROM articles
ORDER BY publish_date DESC NULLS FIRST;

低版本 MySQL 可通过 ORDER BY ISNULL(price), price 模拟。


六、PHP 脚本中处理 NULL

在 PHP 中,需根据变量是否为 null 动态构建 SQL:

php 复制代码
<?php
$conn = mysqli_connect('localhost', 'root', '123456');
mysqli_query($conn, "SET NAMES utf8mb4");
mysqli_select_db($conn, 'YUMING');

// 假设 $count 来自用户输入或配置
$count = $_GET['count'] ?? null; // 可能为 null

if ($count !== null) {
    // 注意:此处应使用预处理防止注入!
    $sql = "SELECT * FROM yuming_test_tbl WHERE yuming_count = " . (int)$count;
} else {
    $sql = "SELECT * FROM yuming_test_tbl WHERE yuming_count IS NULL";
}

$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {
    echo "{$row['yuming_author']} - {$row['yuming_count']}\n";
}
mysqli_close($conn);
?>

建议 :实际项目中必须使用 预处理语句mysqli_prepare)避免 SQL 注入。


七、设计建议:何时允许 NULL?

场景 是否允许 NULL 建议
必填字段(如用户名) ❌ 否 设为 NOT NULL
可选信息(如备注、中间名) ✅ 是 允许 NULL
数值型统计字段 ⚠️ 谨慎 考虑默认值 0 vs NULL
外键字段 ⚠️ 视业务而定 若"可无关联",则允许 NULL

建议

  • 明确字段语义,避免滥用 NULL;
  • 在应用层统一处理 NULL,保持业务逻辑清晰。

小结

判空不用等号比,IS NULL 才是真理;
替换空值用 IFNULL,多备选项 COALESCE
聚合自动跳 NULL,排序位置要留意;
安全等于 <=> 记,设计表时慎用 NULL!

掌握 NULL 的正确处理方式,不仅能避免查询陷阱,还能提升数据质量和系统健壮性。在数据库世界里,理解 NULL,就是理解"未知"的艺术

相关推荐
码云数智-大飞2 小时前
SQL Server 无法启动?常见原因及详细解决方法指南
数据库
8486981192 小时前
MySQL 只读库踩坑实录:为什么 INSERT/UPDATE 不报错,DELETE 却直接炸了?
数据库·mysql·hibernate
没事偷着乐琅2 小时前
二、Pandas 是啥 是数据库吗?
数据库·pandas
rfidunion2 小时前
busybox1.20.2编译过程
数据库
fengsen52113143 小时前
MySQL--》如何在MySQL中打造高效优化索引
android·mysql·adb
_codemonster3 小时前
JavaWeb开发系列(八)数据库环境配置
数据库
小刘的大模型笔记3 小时前
向量数据库实战指南:从部署到RAG落地
数据库
Hello.Reader3 小时前
从 0 到 1 理解硬盘数据恢复工具原理与工程实现
linux·运维·服务器·网络·数据库
前路不黑暗@3 小时前
Java项目:Java脚手架项目的地图服务(十)
java·数据库·spring boot·笔记·学习·spring cloud·maven