och*_*les 29 sql database schema database-design data-modeling
在SQL和关系理论(CJ Date,2009)中,第4章主张避免重复行,并避免NULL存储数据中的属性.虽然我没有避免重复行的麻烦,但我很难看到如何在不使用的情况下对数据进行建模NULL.举个例子来说 - 这有点像下班.
我们有一个artist表,其中包含一gender列.这是gender表的外键.然而,对于一些艺术家来说,我们并不知道他们的性别 - 例如,我们已经获得了一个没有艺术家描述的新音乐列表.如何在不使用的NULL情况下表示这些数据?我看到的唯一解决方案是在gender表格中添加一个新的性别"未知" .
虽然我非常喜欢这本书,但在本章结束时我真的很失望:
当然,如果禁止空值,则必须通过其他方式处理丢失的信息.不幸的是,那些其他手段太复杂了,不能在这里详细讨论.
这是一个真正的耻辱 - 因为这是我等待阅读的解决方案!有一篇参考资料来阅读有很多出版物要阅读的附录,但在我潜入阅读这些内容之前,我希望能有更多的实际总结.
我有几个人评论说他们不明白我为什么要避免'NULL'所以我会再次引用这本书.请执行以下查询:
SELECT s.sno, p.pno
FROM s, p
WHERE s.city <> p.city
OR p.city <> 'Paris'
Run Code Online (Sandbox Code Playgroud)
现在,以s.city为伦敦为例,p.city为Paris.在这种情况下,伦敦<>巴黎,所以查询是真的.现在假设p.city不是Paris,并且实际上是xyz.在这种情况下,(London <> xyz)OR(xyz <> Paris)也是True.所以,给定任何数据 - 这个查询都是真的.但是,如果xyz为"NULL",则场景会发生变化.在这种情况下,这两个表达式既不是True 也不是 False,它们实际上是Unknown.在这种情况下,因为结果未知,您将不会返回任何行.
从2值逻辑到3值逻辑的转变很容易引入这样的错误.事实上,我刚刚在工作中介绍了一个激励这篇文章的内容.我想要所有的行,type != 0然而,这实际上最终匹配type == 0 OR type IS NULL- 令人困惑的行为.
我是否NULL在未来对数据进行建模尚不清楚,但我很好奇其他解决方案是什么.(我也一直认为,如果你不知道,你应该使用NULL).
Per*_*DBA 44
每个人都在说话,除了dportas和Walter之外,没有人能够理解这个问题.好吧,所以有95%的SO人不理解Null问题,并且因为他们的数据库充满了Null而感到受到威胁,他们想要转换寻求者.无价.当他们争论时,有人会如何学习?
为了消除空虚,对你好.我从未在任何数据库中使用Null.
当然,如果禁止空值,则必须通过其他方式处理丢失的信息.不幸的是,那些其他手段太复杂了,不能在这里详细讨论.
实际上它并不那么难.有三种选择.
1.1.第六范式就是答案.但是您不必将整个数据库规范化为6NF.对于每个可选的列,您需要一个远离主表的子表,只需要PK,它也是FK,因为它是1 :: 0-1关系.除PK外,唯一的列是可选列.
看看这个数据模型 ; AssetSerial在第4页是一个经典案例:并非所有人Assets都有SerialNumbers; 但是当他们这样做时,我希望他们存储它们; 更重要的是我想确保它们是独一无二的.
(对于OO人来说,顺便说一下,这是一个关系符号的三级类图,一个"Concwete Table Inheritance",没什么大不了的,我们已经有30年了.)
1.2.对于每个这样的表,使用View来提供表的5NF形式.当然,使用Null(或任何适合该列的值)来标识任何行的列的缺失.但不要通过视图更新.
1.3不要使用直接连接来抓住6NF色谱柱.不要使用外部联接(并且让服务器为缺少的行填充Null).使用子查询填充列,并指定要为缺失值返回的值(除非您有Oracle,因为其子查询处理甚至比其设置处理更差).例如.只是一个例如.您可以将数字列转换为字符串,并对缺失的行使用"Missing".
如果你不想走那么远(6NF),你还有两个选择.
.
2.您可以使用Null替代品.我使用CHAR(0)表示字符colomns,0表示数字.但我不允许FK这样做.显然,您需要一个超出正常数据范围的值.这不允许三值逻辑.
.
3.除了(2)之外,对于每个Nullable列,您需要一个布尔指示符.对于Sex列的示例,指标将类似于SexIsMissing或SexLess(抱歉).这允许非常紧凑的三值逻辑.5%的人中有很多人喜欢它,因为数据库仍然是5NF(并且表格较少); 缺少信息的列加载了从未使用过的值; 它们仅在指标为假时使用.如果您有一个企业数据库,则可以将其包装在一个Function中,并始终使用UDF,而不是原始列.
当然,在所有情况下,您都永远无法编写处理缺失信息所需的代码.是否ISNULL()为6NF列的子查询,或者在使用该值之前要检查的指示符,还是UDF.
如果Null具有特定含义......那么它就不是空的!根据定义,Null是未知值.
Wal*_*tty 19
那你如何设计没有NULLS?这是最初的问题.
这实际上非常简单.你设计的是,每当你不得不丢失一些数据时,你可以通过丢失整行来实现.如果没有行,则不是一行满NULL.它显然不存在.
因此,在"DateOfDeath"的情况下,我们有一个包含两列的表,即PersonId和DateOfDeath.PersonId在Persons表中引用Id.如果没有要存储的DateOfDeath,我们不存储该行.讨论结束.
如果你在这个和Persons表之间进行OUTER JOIN,那么只要没有行,你就会得到DateOfDeath的NULL.如果你在where子句中使用它,你会得到关于3值逻辑的常见的令人困惑的行为.如果执行INNER JOIN,那么没有DateOfDeath的行将从连接中消失.
说了这么多,我经常在非关键列中允许NULL.而且我没有简明扼要的方式告诉您如何确定列是否至关重要.
nulls 是理论满足现实的结果,必须进行调整才能使用。在我看来,null与仅null在适当的地方使用相比,试图避免所有值最终会导致更丑陋和更不易维护的代码。
| 归档时间: |
|
| 查看次数: |
5991 次 |
| 最近记录: |