在mysql数据库的字段值处理中,NULL值和空字符串是两种完全不同的取值,很多新手开发者会误认为两者等价,实际两者在存储逻辑、查询规则、函数处理等多个方面都存在明显差异,理解这些差异对数据库设计和业务逻辑实现都有重要意义。

NULL值和空字符串的基本定义
NULL在mysql中表示字段没有值,是一个未知的、不存在的状态,不属于任何数据类型。而空字符串是一个长度为0的字符串类型值,属于字符串数据类型的合法取值,本质是存储了一个没有字符内容的字符串。
存储方式的差异
mysql对NULL值和空字符串的存储逻辑完全不同:
- NULL值不会占用实际的存储空间,mysql会在字段的NULL标志位中标记该字段为NULL,具体存储时仅记录标记位信息。
- 空字符串会占用实际的存储空间,对于varchar类型的字段,空字符串会占用1到2个字节的长度记录信息,具体占用空间和字符集有关。
查询判断的差异
查询时判断NULL值和空字符串的规则完全不同,不能使用普通的比较运算符处理NULL:
NULL值的查询判断
判断字段是否为NULL,必须使用IS NULL或者IS NOT NULL,不能使用等于号或者不等于号,因为NULL和任何值比较的结果都是NULL,不会被匹配到。
-- 正确查询NULL值的写法 SELECT * FROM user_table WHERE username IS NULL; -- 错误写法,不会返回任何结果 SELECT * FROM user_table WHERE username = NULL;
空字符串的查询判断
空字符串是普通的字符串值,可以使用等于号或者不等于号进行判断,也可以使用IS NULL判断,但结果为false,因为空字符串不是NULL。
-- 查询空字符串的正确写法 SELECT * FROM user_table WHERE username = ''; -- 查询非空字符串的写法 SELECT * FROM user_table WHERE username != '';
函数处理的差异
大部分mysql内置函数处理NULL值和空字符串的逻辑不同:
- NULL值参与运算或者函数处理时,结果通常也是NULL,比如
CONCAT('a', NULL)的结果是NULL。 - 空字符串参与运算时会被当作正常的字符串处理,比如
CONCAT('a', '')的结果是'a'。 - 聚合函数如
COUNT()统计时会忽略NULL值,但是会统计空字符串,SUM()、AVG()等函数也会忽略NULL值,空字符串如果参与数值运算会被转换为0。
以下是常见函数处理两者的结果对比:
| 函数/运算 | 传入NULL的结果 | 传入空字符串的结果 |
|---|---|---|
| CONCAT('test', 参数) | NULL | test |
| LENGTH(参数) | NULL | 0 |
| COUNT(参数) | 不计入统计 | 计入统计 |
| 参数 + 1 | NULL | 1(空字符串转数值为0,0+1=1) |
索引和默认值的差异
在索引使用上,mysql的普通索引可以存储空字符串,但是对NULL值的处理取决于存储引擎,比如InnoDB存储引擎的B树索引会存储NULL值,但是NULL值不会参与部分索引优化逻辑。在字段默认值设置上,如果字段允许NULL,默认值可以是NULL,也可以手动设置为空字符串,两者是独立的默认值选项。
实际开发中的选择建议
实际开发中需要根据业务场景选择使用NULL还是空字符串:
- 如果字段表示未知、未填写的状态,比如用户的可选昵称,用户没有填写时适合用NULL表示。
- 如果字段表示明确的空内容,比如用户的简介,用户主动填写了空内容,适合用空字符串表示。
- 如果字段需要参与数值运算或者聚合统计,建议设置默认值不为NULL,避免NULL值导致运算结果不符合预期。