NULL与空字符串的区别:数据库专家详解
1. NULL的概念解析
1.1 NULL的定义
在数据库系统中,NULL是一个特殊标记,表示"未知"或"不存在"的值。它不是任何数据类型的实例,而是表示缺失值的标记。
go专栏:https://duoke360.com/tutorial/path/golang
关键结论:NULL不是空值、不是零、不是空字符串,而是表示"值未知"或"无值"的状态标记。
1.2 NULL的三值逻辑
与常规的二值逻辑(真/假)不同,引入NULL后数据库使用三值逻辑:
- TRUE
- FALSE
- UNKNOWN (由NULL引起)
SELECT 1 = NULL; -- 结果不是TRUE或FALSE,而是NULL(UNKNOWN)
SELECT NULL IS NULL; -- 这才是TRUE
2. 空字符串的概念
2.1 空字符串定义
空字符串(‘’)是一个确定的值,它是长度为0的字符串。在内存中会分配存储空间,只是内容为空。
关键区别:空字符串是字符串类型的有效值,而NULL表示该字段没有值。
2.2 空字符串的存储
不同数据库对空字符串的处理:
- MySQL:区分NULL和’'(空字符串)
- Oracle:将空字符串视为NULL
- SQL Server:区分NULL和’’
3. NULL与空字符串的核心区别
3.1 语义差异
特性 | NULL | 空字符串(‘’) |
---|---|---|
语义 | 未知/不存在 | 已知的空值 |
数据类型 | 无类型 | 字符串类型 |
存储表示 | 无存储 | 有存储 |
比较操作 | 需用IS NULL | 用= ‘’ |
3.2 存储与索引差异
- NULL通常不占用存储空间(除标记位外)
- 空字符串会占用存储空间(至少是长度标识)
- 在B树索引中,NULL值通常不被索引(除非创建过滤索引)
-- 创建测试表
CREATE TABLE test_values (
id INT PRIMARY KEY,
null_col VARCHAR(100) NULL,
empty_col VARCHAR(100) NOT NULL DEFAULT ''
);
-- NULL不占用空间(除NULL标记位)
INSERT INTO test_values(id, null_col) VALUES(1, NULL);
-- 空字符串占用空间
INSERT INTO test_values(id, empty_col) VALUES(2, '');
4. 实际应用场景
4.1 何时使用NULL
- 表示信息缺失(如未知的手机号)
- 表示不适用(如未婚人士的配偶姓名)
- 作为外键表示无关联记录
4.2 何时使用空字符串
- 表示明确无内容(如中间名可为空的姓名)
- 需要字符串操作的字段(如CONCAT处理)
- 需要默认值但内容为空的情况
5. 面试常见问题解析
5.1 经典面试题示例
问题:以下SQL查询结果有何不同?
SELECT * FROM users WHERE phone = '';
SELECT * FROM users WHERE phone IS NULL;
SELECT * FROM users WHERE phone IS NULL OR phone = '';
专家解答:
- 第一个查询找出phone为空字符串的记录
- 第二个查询找出phone为NULL的记录
- 第三个查询找出phone为NULL或空字符串的所有记录
5.2 聚合函数处理差异
SELECT
COUNT(*), -- 统计所有行
COUNT(column), -- 统计非NULL行
SUM(column), -- NULL视为0
AVG(column) -- 忽略NULL值
FROM table;
重要提示:COUNT(*)计算所有行数,COUNT(column)只计算非NULL值
6. 最佳实践建议
- 一致性原则:在整个数据库中统一NULL的使用规范
- NOT NULL约束:对于必须有值的列显式声明NOT NULL
- COALESCE函数:处理NULL值转为默认值
COALESCE(col, 'N/A')
- NULLIF函数:将特定值转为NULL
NULLIF(col, '')
- 索引考虑:注意NULL值在索引中的特殊行为
7. 高级话题延伸
7.1 NULL与性能
- 空间:NULL通常比空字符串占用更少空间
- 索引:NULL值可能不被B树索引包含(取决于DBMS)
- 查询优化:
IS NULL
条件可能导致全表扫描
7.2 各数据库实现差异
数据库 | NULL排序位置 | 空字符串处理 |
---|---|---|
MySQL | 最小值 | 区分NULL和’’ |
Oracle | 最大值 | ''视为NULL |
SQL Server | 最小值 | 区分NULL和’’ |
PostgreSQL | 最大值 | 区分NULL和’’ |
掌握这些区别对于跨数据库应用开发至关重要。