在MySQL中,NULL值用来表示数据缺失或未知状态,它既不是数字0,也不是空字符串。理解NULL在表结构、查询和统计中的表现,对数据库设计和程序逻辑都十分关键。

NULL与空值的区别
很多初学者会把NULL和空字符串''混为一谈,实际上两者在MySQL中完全不同。NULL代表没有值,而空字符串是一个长度为0的字符串值。
| 对比项 | NULL | 空字符串 |
|---|---|---|
| 含义 | 未知或缺失 | 已知为空 |
| 长度 | NULL | 0 |
| 等值比较 | 不能用=判断 | 可用=判断 |
建表时如何定义NULL
在创建数据表时,可以通过NOT NULL来禁止字段存储NULL,也可以显式允许NULL。下面给出一个简单的建表示例:
CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NULL, age INT ); -- name不允许为NULL -- email允许为NULL -- age未声明,默认允许NULL
查询中的NULL处理
不能使用等号=来判断NULL,必须使用IS NULL或IS NOT NULL。错误写法会导致查不到数据。
-- 错误写法,不会返回任何行 SELECT * FROM user WHERE email = NULL; -- 正确写法 SELECT * FROM user WHERE email IS NULL; SELECT * FROM user WHERE email IS NOT NULL;
统计函数与NULL
COUNT(*)会统计所有行,而COUNT(字段)会忽略该字段为NULL的行。SUM、AVG等聚合函数同样忽略NULL。
SELECT COUNT(*) AS total, COUNT(email) AS has_email FROM user;
排序时NULL的位置
在ORDER BY中,MySQL默认把NULL视为最小值,升序时NULL排在最前。可以使用IS NULL配合排序改变位置。
SELECT * FROM user ORDER BY email IS NULL, email;
程序中的注意事项
在代码里读取NULL时,多数语言会映射为None或null,而不是空字符串。以Python为例:
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='test', db='demo')
cur = conn.cursor()
cur.execute("SELECT email FROM user WHERE id = 1")
row = cur.fetchone()
# 如果email为NULL,row[0]是None
if row[0] is None:
print("邮箱未填写")
else:
print("邮箱:", row[0])
设计建议
- 业务逻辑上必须有值的字段,尽量设为NOT NULL,并用默认值代替NULL。
- 可选信息且确实可能未知时,再允许NULL。
- 注意索引字段含NULL会增加复杂度,联合索引中NULL可能影响命中。
合理看待MySQL中的NULL值,才能写出更稳健的表结构和查询语句。