SQL and Relational Theory(C.J.Date,2009)中,第4章主张避免重复行,并避免存储数据中的NULL个属性.虽然避免重复行没有问题,但我正在努力了解如何在不使用NULL的情况下对数据建模.以以下内容为例——这是工作中的一部分.

我们有一个artist表,其中有gender列.这是gender表的外键.然而,对于一些艺术家,我们不知道他们的性别-例如,我们收到了一份新音乐 list ,其中没有对艺术家的描述.在不使用NULL的情况下,如何表示该数据呢?我看到的唯一解决办法是在gender表中增加一个新的性别,"未知".

虽然我非常喜欢这本书,但当这一章以以下内容结束时,我真的很失望:

当然,如果是禁止空的,那麽遗漏的资料便要用其他方法来处理.不幸的是,这些其他方法太复杂了,不能在这里详细讨论.

这真是一个耻辱-因为这就是我等待阅读的解决方案!附录中有一个参考资料,里面有很多出版物可供阅读,但在我开始阅读这些之前,我希望能有更多一点实事求是的总结.


我得到了一些人的 comments ,他们不理解我为什么要避免‘null’,所以我会再次引用这本书.接受以下查询:

SELECT s.sno, p.pno
  FROM s, p
 WHERE s.city <> p.city
    OR p.city <> 'Paris'

Now, take the example that s.city is London, and p.city is Paris. In this case, London <> Paris, so the query is true. Now take the case that p.city is not Paris, and is infact xyz. In this case, (London <> xyz) OR (xyz <> Paris) is also True. So, given any data - this query is true. However, if xyz is 'NULL' the scenario changes. In this case both of these expressions are neither True nor False, they are in fact, Unknown. And in this case because the result is unknown you will not get any rows returned.

从2值逻辑转移到3值逻辑很容易引入这样的错误.事实上,我刚刚在工作中介绍了一个,正是它激发了我的这个帖子.我想要type != 0位所在的所有行,然而,这实际上最终与type == 0 OR type IS NULL匹配-令人困惑的行为.

我对future 的数据建模是否使用NULL还不清楚,但我很好奇其他解决方案是什么.(我也一直认为,如果你不知道,你应该使用NULL).

推荐答案

你干得不错,因为你消除了NULL.我从未允许在我的任何数据库中使用NULL.

Of course, if nulls are prohibited, then missing information will have to be handled by some other means. Unfortunately, those other means are much too complex to be discussed in detail here.

其实一点也不难.有三种 Select .

  1. 这里有一篇由H·达尔文 compose 的关于How To Handle Missing Information Without Using NULL的论文,它可能会帮助你理解这个问题.

    1.1.第六范式是答案.但是您不必将您的entire数据库正常化到6NF.对于可选的每一列,您需要主表之外的子表,只有主键,这也是FK,因为它是1::0-1关系.除主键外,唯一列为可选列.

    看看这个Data Model;第4页的AssetSerial是一个典型的例子:不是所有的Assets都有SerialNumbers;但当它们有SerialNumbers时,我希望它们存储起来;更重要的是,我想确保它们是唯一的.

    (顺便说一句,对于那些面向对象的人来说,这是一个关系表示法中的三层类图,"具体的表继承",没什么大不了的,我们已经有30年了.)

    1.2.对于每个这样的表格,使用视图来提供表格的5NF表单.当然,可以使用Null(或适用于该列的任何值)来标识任何行是否缺少该列.但不要通过视图进行更新.

    1.3不要使用直管接头抓住6NF柱.也不要使用外部联接(并让服务器为缺少的行填充Null).使用子查询填充列,并指定要为缺少的值返回的值(Oracle除外,因为它的子查询处理甚至比它的集合处理更糟糕).你可以把一个数字列转换成字符串,并用"Missing"表示缺少的行.

当您不想走那么远(6NF)时,您还有两个 Select .

  1. 您可以使用Null替换.我使用CHAR(0)表示字符列,使用0表示数字.但我不允许FKS这样做.显然,您需要一个超出正常数据范围的值.这不允许三值逻辑.

  2. 除了(2)之外,对于每个可为空的列,还需要一个布尔指示符.以Sex列为例,指示符应该是SexIsMissingSexLess(抱歉).这允许非常严格的三值逻辑.在这5%的人群中,许多人喜欢它,因为db保持在5NF(更少的表格);缺少信息的列会加载从未使用过的值;仅当指示器为假时才使用.如果你有一个企业数据库,你可以把它包装在一个函数中,并且总是使用UDF,而不是raw列.

当然,在所有情况下,您都无法避免编写处理丢失信息所需的代码.它是ISNULL()、6NF列的子查询、使用值之前要判断的指示符或UDF.

If Null has a specific meaning ...那么它不是空的!根据定义,Null是未知值.

Database相关问答推荐

MongoDB根据嵌套文档中的值匹配数组

MongoDB事务,回调API方法

避免数据库联接的两个查询替换

如何高效地存储棋局?

我们可以出于不同目的在同一 postgres 数据库上同时进行物理和逻辑复制吗?

如何决定使用数据库事务

什么是Open Schema的数据库?

Postgresql:优化数字字段的列大小

阿拉伯字符串上的 WHERE 子句匹配问题

Laravel 5 从 URL 获取 ID

ORM 性能成本

Django:如何以线程安全的方式执行 get_or_create()?

在 SQL SERVER 中监视 SQL 查询的进度

避免从网站数据库中data scraping数据抓取?

使用 JSON 作为存储/传输格式的数据库

如何在 SQL Server 中创建数据库的别名

在 MYSQL 的子查询中使用 LIMIT 关键字的替代方法

为什么 DBMS 不支持 ASSERTION

您是否应该将自引用表列设为外键?

带数据库的Electron 应用程序