NULL与空字符串的区别:数据库专家详解

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

  1. 表示信息缺失(如未知的手机号)
  2. 表示不适用(如未婚人士的配偶姓名)
  3. 作为外键表示无关联记录

4.2 何时使用空字符串

  1. 表示明确无内容(如中间名可为空的姓名)
  2. 需要字符串操作的字段(如CONCAT处理)
  3. 需要默认值但内容为空的情况

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 = '';

专家解答

  1. 第一个查询找出phone为空字符串的记录
  2. 第二个查询找出phone为NULL的记录
  3. 第三个查询找出phone为NULL或空字符串的所有记录

5.2 聚合函数处理差异

SELECT 
    COUNT(*),          -- 统计所有行
    COUNT(column),     -- 统计非NULL行
    SUM(column),       -- NULL视为0
    AVG(column)        -- 忽略NULL值
FROM table;

重要提示:COUNT(*)计算所有行数,COUNT(column)只计算非NULL值

6. 最佳实践建议

  1. 一致性原则:在整个数据库中统一NULL的使用规范
  2. NOT NULL约束:对于必须有值的列显式声明NOT NULL
  3. COALESCE函数:处理NULL值转为默认值 COALESCE(col, 'N/A')
  4. NULLIF函数:将特定值转为NULL NULLIF(col, '')
  5. 索引考虑:注意NULL值在索引中的特殊行为

7. 高级话题延伸

7.1 NULL与性能

  • 空间:NULL通常比空字符串占用更少空间
  • 索引:NULL值可能不被B树索引包含(取决于DBMS)
  • 查询优化IS NULL条件可能导致全表扫描

7.2 各数据库实现差异

数据库 NULL排序位置 空字符串处理
MySQL 最小值 区分NULL和’’
Oracle 最大值 ''视为NULL
SQL Server 最小值 区分NULL和’’
PostgreSQL 最大值 区分NULL和’’

掌握这些区别对于跨数据库应用开发至关重要。