关系型数据库中的 NULL
第 1.6 课 · 阅读时间:约 6 分钟 · 练习题 ↓
NULL 是关系型数据库在值缺失、未知或不适用时使用的特殊标记。本课你将了解 NULL 的含义、它不是什么、数据库为什么需要它、哪些列可以包含它,以及为什么有了 NULL,数据库会回答"未知",而不是"是"或"否"。
在前面的课程中,我们学习了表、行、列和数据类型。表中的每个单元格都存储着其列类型的值-除非根本没有值可存。
NULL 意味着什么?
NULL 不是一个值,而是一个标记:它表示该单元格没有值。原因可能不同-值未知、不适用于这一行,或者只是还没有出现。
表中的 NULL
Sakila 数据库的 rental 表存储电影租赁记录。只有电影归还后,租赁记录才会有 return_date,在此之前该单元格为 NULL:
| rental_id | rental_date | return_date |
|---|---|---|
| 14098 | 2005-08-21 00:30:32 | NULL |
| 14469 | 2005-08-21 13:07:24 | 2005-08-24 10:37:24 |
| 14626 | 2005-08-21 18:35:44 | 2005-08-25 23:54:44 |
租赁 14098 还没有归还:它的归还日期还不存在。这既不是"零",也不是"空日期"-那里什么都没有。
NULL 不是什么
- NULL 不是 0。 零是一个真正的数字:价格为 0 表示"免费",价格为 NULL 表示"价格未知"。
- NULL 不是空字符串。
''是没有字符的文本,是一个已知的值。NULL 表示根本没有文本。 - NULL 不是单词 'NULL'。 文本
'NULL'是一个由四个字母组成的普通字符串。 - NULL 不是 false。 在数据库逻辑中,NULL 表示"未知",而不是"否"。
数据库为什么使用 NULL?
如果没有 NULL,每个缺失值都需要一个编造的占位符,比如 0、'' 或 1900-01-01,而这些占位符会和真实数据混在一起。NULL 如实地涵盖了典型情况:
- 未知: 客户没有提供电话号码。
- 不适用: 个人没有公司的税号。
- 尚未知道: 在电影归还之前,租赁记录没有归还日期。
哪些列可以包含 NULL?
一列是否接受 NULL,是在设计表的时候决定的。声明为 NOT NULL 的列必须始终有值:在 rental 中,rental_date 是必填的,而 return_date 可以为空。主键永远不能为 NULL:每一行都必须能够被识别。
一条实用的规则:只在缺失值确实有意义的地方允许 NULL,其他一律设为 NOT NULL。
计算中的 NULL
如果表达式中用到了 NULL,结果通常也是 NULL,因为一个未知的值会让整个结果变得未知:
10 + NULL结果是 NULL。5 * NULL结果是 NULL。- 租赁日期与为 NULL 的归还日期之间相差的天数也是 NULL-租赁还没有结束。
三值逻辑
通常一个条件要么为真,要么为假。有了 NULL,就出现了第三种答案:UNKNOWN("未知")。租赁 14098 是在 8 月 25 日之前归还的吗?它的归还日期未知,所以诚实的回答是"未知"。
把 NULL 和 NULL 比较也是如此:两个未知的值是否相等无法确定,所以 NULL = NULL 同样是 UNKNOWN,而不是真。正因为如此,数据库为 NULL 提供了专门的检查方式,而不是使用普通的比较-当你开始编写查询时就会用到它们。
本课要点:
- NULL 标记缺失的值:未知、不适用或尚未知道。
- NULL 不是 0,不是空字符串,不是文本 'NULL',也不是 false。
- 声明为 NOT NULL 的列和主键不能包含 NULL;其他列可以。
- 含有 NULL 的计算通常结果为 NULL。
- 与 NULL 的比较会得到第三种逻辑结果 UNKNOWN;就连 NULL = NULL 也是 UNKNOWN。
常见问题
NULL 和空字符串一样吗?
不一样。空字符串 '' 是一个已知的、没有字符的文本值。NULL 表示根本没有值。
NULL 等于 NULL 吗?
在通常意义上不等于。每个 NULL 都代表一个未知的值,无法证明两个未知的值相等,所以把 NULL 和 NULL 比较的结果是 UNKNOWN。
任何列都可以包含 NULL 吗?
任何类型的列-数字、文本或日期-都可以包含 NULL,除非表用 NOT NULL 禁止。主键列永远不接受 NULL。
面试题
在面试中你会如何解释 NULL?
NULL 是表示缺失值的标记:未知、不适用或尚未知道。它不是零、不是空字符串,也不是 false,并且遵循自己的规则:含有 NULL 的计算返回 NULL,与它的比较返回 UNKNOWN。
什么是三值逻辑?
在 SQL 中,条件可以是 TRUE、FALSE 或 UNKNOWN。只要比较中涉及 NULL,就会出现 UNKNOWN,因为数据库无法判断一个未知的值是否满足条件。
为什么主键不能为 NULL?
主键用于识别一行。未知的标识符做不到这一点:两行主键都为 NULL 时将无法区分,因此数据库不允许主键列中出现 NULL。