问题描述
我已经阅读了几篇关于license plate value of NULL(约Droogie的DEF CON 27)的文章,其中包括第三章 Little Data Humble Pi的书籍 Matt Parker (谈论Steve Null),其中在数据库中存储字符串值“ NULL”与 NULL 值。
我使用的数据库(至少是AFAIK)具有"NULL" isn't the same as a NULL值。字段的状态是从值NULL is stored separately开始。
像这样的SQL
SELECT bar
FROM foo
WHERE foobar IS NULL;
将不同于
SELECT bar
FROM foo
WHERE foobar = 'NULL';
当我第一次听到这些故事时,我以为它们一定是都市传奇,但在看到更多故事之后,我想知道我是否想念一些东西?是否有一些数据库无法将“ NULL”与是NULL 区别开来(如果是,是哪个数据库,任何当前数据库)?还是由谁构建数据库应用程序来存储“ NULL”作为 NULL 值的字符串或其他一些不良设计的问题?
进一步阅读:
- BBC on Jennifer Null
- Mashable on Droogie's DEF CON Talk
- Matt Parker on Steve Null
- Passing NULL as a surname in SOAP
- Droogie's Go NULL Yourself talk from Def Con 27
- Droogie finally got his plate renewed
总结我的问题:
- 某些数据库是否对NULL和“ NULL”进行了错误处理?
- 是仅历史数据库,还是目前有相同的数据库?
- 是否有逻辑原因使体系结构POV中的“ NULL”等于IS NULL?
- 还是所有这些都是应用程序设计失败的示例?
- 你怎么能把它搞糟呢?
我真的很乐意看到一些将NULL和'NULL'混淆的SQL的示例。
解决方法
这是设计缺陷。 “ NULL”是一个字符串,您不必使用字符串来表示Nothing。因此,在一种情况下,您正在寻找的填充值恰好是“ NULL”,而对于IS NULL,实际上没有任何填充。
,您要描述两个不同的概念:
-
在关系数据库中,
'null'
是一个CHAR
值(长度为4),就这么简单。 -
null
的另一面不是值,但表示“缺失值”。这也不是没有价值。表示“该值确实存在,但我们无法恢复它。”
因此,它们都是非常不同的概念。我不知道在您显示它时会错误处理null的数据库。但是,我想到的应用程序并不能很好地区分它们。我会认为该应用程序存在缺陷,而不是数据库引擎本身存在缺陷。
无论如何,以下是PostgreSQL中的一些SQL表达式及其值,以说明上述定义:
select
'null' = 'null',-- 1. TRUE
'null' = null,-- 2. null (actually UNKNOWN)
'null' <> null,-- 3. null (actually UNKNOWN)
'null' is null,-- 4. FALSE
'null' is not null,-- 5. TRUE
null is null,-- 6. TRUE
null is not null,-- 7. FALSE
null = null,-- 8. null (actually UNKNOWN)
null <> null,-- 9. null (actually UNKNOWN)
null is not distinct from null,-- 10. TRUE
(null = null) is unknown,-- 11. TRUE
(null = null) is true,-- 12. FALSE
(null = null) is false,-- 13. FALSE
(null <> null) is unknown -- 14. TRUE
请参见DB Fiddle上的运行示例。
注意。当您通常与null
比较时,结果是真实值UNKNOWN
,而不是TRUE
,而不是FALSE
。但是,大多数数据库驱动程序在将该值发送到您的应用程序时会将其转换为null
,如您在上述#2,#3,#8和#9的情况中所见。