从DB模型中消除NULLable列的选项(为了避免SQL的三值逻辑)?
不久之前,我一直在阅读
SQL and Relational Theory by C. J. Date一书.作者因批评SQL的三值逻辑(3VL)而闻名.1)
作者强调了为什么在SQL中应该避免使用3VL,但他没有概述如果不允许使用可空列的数据库模型的样子.我已经考虑了一下,并提出了以下解决方案.如果我错过了其他设计方案,我想听听他们的意见! 1)日期对SQL 3VL的批评反过来也受到批评:见this paper by Claude Rubinson(包括C. J. Date的原始批评). 示例表: 作为示例,请使用下表,其中我们有一个可为空的列(DateOfBirth): # +-------------------------------------------+ # | People | # +------------+--------------+---------------+ # | PersonID | Name | DateOfBirth | # +============+--------------+---------------+ # | 1 | Banana Man | NULL | # +------------+--------------+---------------+ 选项1:通过标志和默认值模拟NULL: 不是使列可为空,而是指定任何默认值(例如1900-01-01).另一个BOOLEAN列将指定是否应该简单地忽略DateOfBirth中的值或者它是否实际包含数据. # +------------------------------------------------------------------+ # | People' | # +------------+--------------+----------------------+---------------+ # | PersonID | Name | IsDateOfBirthKnown | DateOfBirth | # +============+--------------+----------------------+---------------+ # | 1 | Banana Man | FALSE | 1900-01-01 | # +------------+--------------+----------------------+---------------+ 选项2:将可为空的列转换为单独的表: 可空列由新表(DatesOfBirth)替换.如果记录没有该列的数据,则新表中将不会有记录: # +---------------------------+ 1 0..1 +----------------------------+ # | People' | <-------> | DatesOfBirth | # +------------+--------------+ +------------+---------------+ # | PersonID | Name | | PersonID | DateOfBirth | # +============+--------------+ +============+---------------+ # | 1 | Banana Man | # +------------+--------------+ 虽然这似乎是更好的解决方案,但这可能会导致需要为单个查询加入许多表.由于不允许OUTER JOIN(因为它们会在结果集中引入NULL),所以可能不再像以前那样只使用一个查询来获取所有必需的数据. 题: 解决方法我看到Date的同事Hugh Darwen在一个很好的演示文稿“如何处理不使用NULL的信息丢失”中讨论了这个问题,该文件于 the Third Manifesto website年发布.他的解决方案是您第二种方法的变体.它是第六种常规形式,其中包含用于保存出生日期和未知标识符的表格: # +-----------------------------+ 1 0..1 +----------------------------+ # | People' | <-------> | DatesOfBirth | # +------------+----------------+ +------------+---------------+ # | PersonID | Name | | PersonID | DateOfBirth | # +============+----------------+ +============+---------------+ # | 1 | Banana Man | ! 2 | 20-MAY-1991 | # | 2 | Satsuma Girl | +------------+---------------+ # +------------+----------------+ # 1 0..1 +------------+ # <-------> | DobUnknown | # +------------+ # | PersonID | # +============+ # | 1 | # +------------+ 从People中选择然后需要加入所有三个表,包括样板,以指示未知的出生日期. 当然,这在某种程度上是理论上的.这些天的SQL状态仍然不够先进,无法处理所有这些.休的介绍涵盖了这些缺点.他提到的一件事并不完全正确:SQL的某些版本确实支持多个赋值 – 例如Oracle’s INSERT ALL syntax. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |