Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 关系数据库中的空值可以吗?_Database Design_Oop_Null - Fatal编程技术网

Database design 关系数据库中的空值可以吗?

Database design 关系数据库中的空值可以吗?,database-design,oop,null,Database Design,Oop,Null,有一个学派认为关系数据库中不允许空值。也就是说,表的属性(列)不应允许空值。来自软件开发背景,我真的不明白这一点。如果null在属性的上下文中有效,那么应该允许它。这在Java中非常常见,因为对象引用通常为空。由于没有丰富的数据库经验,我想知道我是否遗漏了一些内容。空标记可以。确实如此。从数据库规范化的角度来看,空值是负面的。其思想是,如果一个值可以是空的,那么您真的应该将其拆分为另一个稀疏表,这样您就不需要为没有值的项指定行 这是为了确保所有数据都是有效的和有价值的 但是,在某些情况下,使用n

有一个学派认为关系数据库中不允许空值。也就是说,表的属性(列)不应允许空值。来自软件开发背景,我真的不明白这一点。如果null在属性的上下文中有效,那么应该允许它。这在Java中非常常见,因为对象引用通常为空。由于没有丰富的数据库经验,我想知道我是否遗漏了一些内容。

空标记可以。确实如此。从数据库规范化的角度来看,空值是负面的。其思想是,如果一个值可以是空的,那么您真的应该将其拆分为另一个稀疏表,这样您就不需要为没有值的项指定行

这是为了确保所有数据都是有效的和有价值的

但是,在某些情况下,使用null字段很有用,特别是当您出于性能原因希望避免再次加入时(尽管如果数据库引擎设置正确,这不应该是一个问题,除非在非常高的性能场景中)


-Adam

对数据字段使用NULL没有什么错。将键设置为null时必须小心。主键不应为空。外键可以为null,但必须小心不要创建孤立记录


如果某个内容“不存在”,则应使用NULL,而不是空字符串或其他类型的标志。

根据严格的关系代数,不需要NULL。然而,对于任何实际项目,它们都是必需的

首先,许多真实世界的数据是未知的或不适用的,空值很好地实现了这种行为。其次,它们使视图和外部联接更加实用。

这取决于具体情况

只要您了解为什么允许数据库中的
NULL
s(需要根据每列进行选择),以及您将如何解释、忽略或以其他方式处理它们,就可以了

例如,像
NUM\u CHILDREN
这样的列-如果您不知道答案怎么办-它应该是
NULL
。在我看来,该列的设计没有其他最佳选项(即使您有一个标志来确定
NUM_CHILDREN
列是否有效,您仍然必须在该列中有一个值)

另一方面,如果您不允许
NULL
s,并且在某些情况下有特殊的保留值(而不是标志),例如-1表示真正未知的子项数,那么您必须以类似的方式在约定、文档等方面解决这些问题

因此,最终,这些问题必须通过公约、文件和一致性来解决

亚当·戴维斯(Adam Davis)在上述回答中明确支持的另一种方法是,将列标准化为稀疏(或者在
NUM_CHILDREN
示例或大多数数据具有已知值的任何示例中,不是如此稀疏)表,同时能够消除所有空值,但在一般实践中是不可行的

在许多属性未知的情况下,为每一列连接到另一个表是没有意义的,因为在更简单的设计中,
NULL
s可以允许。连接的开销、主键的空间要求在现实世界中没有什么意义


这让我们想起了通过添加基数列来消除重复行的方法,同时从理论上解决了没有唯一键的问题,实际上这有时是不可能的——例如,在大规模数据中。纯粹主义者很快就提出了一个代理PK,然而一个无意义的代理可以构成关系(表)中元组(行)的一部分从关系理论的角度来看,这很可笑。

你会发现,在逐步数据采集系统中,你无法避免数据库中出现空值,因为提问/数据收集的顺序很少与逻辑数据模型匹配

或者您可以设置默认值(需要代码来处理这些默认值)。例如,在您的模型中,您可以假设所有字符串都是空的而不是空的


或者,您可以使用用于数据采集的暂存数据库表,该数据库表将持续进行,直到在填充实际数据库表之前获得所有数据。这是一个很大的额外工作。

我想说,肯定应该使用空值。没有其他正确的方法来表示缺少数据。例如,使用空字符串表示缺少的地址行是错误的,或者使用0表示缺少的年龄数据项是错误的。因为空字符串和0都是数据。Null是表示这种情况的最佳方式。

反对Null的一个理由是它们没有定义良好的解释。如果字段为空,则可解释为以下任一情况:

  • 该值为“Nothing”或“Empty set”
  • 对于该字段,没有意义的值
  • 该值未知
  • 尚未输入该值
  • 该值为空字符串(对于不区分空字符串和空字符串的数据库)
  • 某些特定于应用程序的含义(例如,“如果值为null,则使用默认值”。)
  • 发生了一个错误,导致该字段的值为空,而实际上不应该为空

一些模式设计者要求所有的值和数据类型都有定义良好的解释,因此空值是不好的。

对于数据库,空值转换为“我没有这个值”。这意味着(有趣的是),允许null的布尔列是完全可以接受的,并且出现在许多数据库模式中。相反,如果您的代码中有一个布尔值,它的值可以是“真”、“假”或“未定义”,那么您很可能会看到您的代码迟早会出现在DailyWF上
CREATE TABLE Customer (ID int PRIMARY KEY, Name varchar(100) NOT NULL, Address varchar(200) NOT NULL);
CREATE TABLE CustomerPhone (ID int PRIMARY KEY, Phone varchar(20) NOT NULL, CONSTRAINT FK_CustomerPhone_Customer FOREIGN KEY (ID) REFERENCES Customer (ID));
  SELECT FullName = COALESCE(FirstName + ' ', '') + COALESCE(MiddleName+ ' ', '') + COALESCE(FamilyName, '') FROM Person
where bitfield in (1,0)
select * from mytable
where id not in (select id from excludetable)
select * from mytable
where id <> NULL and id <> 1