我有一个关于在数据库中对外键列使用null与默认值的问题。在设计数据库时,我发现了很多关于null与默认值的相反意见,但不完全是外键(主要优点和缺点)。
目前我正在设计一个新数据库,它将为不同的Web应用程序和其他具有不同数据访问方法(ORM,存储过程)的系统存储大量数据,并且我希望尽可能在最低级别实现一般规则(数据库)。 (所以不要在以后的应用程序中担心这个规则。)
为了举个例子,假设我有一个用户User
表,其中包含国籍NationalityID
的外键列,这是表CountryID
的主键Country
}。
现在我有两个/三个选项:
答:我允许NationalityID
列(以及数据库中所有其他类似的外键列)为空,只需坚持使用常用方法检查null(在应用程序中应用规则)
或
B:我为每个外键指定一个默认值,让它说“-1”,并在每个关系表中添加“-1”作为键,所有其他数据作为“无数据”(为此在Country
表中的示例我将CountryID为“-1”的列和CountryName
的“我设置为”无数据“的列)。因此,每当我想知道用户的国籍时,我总是会得到没有额外代码规则的结果(我不需要检查它是否为空)。
或
C:我可以禁止外键的空值。但这确实是我想要避免的。 (如果不是附加数据(用户国籍),我需要选择至少存储基本数据(用户名))
B好的方法是不是?我在这里错过了什么?我通过这种方法获得了更多的收益吗?我可以遇到哪些问题(除了小心在ID值为“-1”的关系表中总是有额外的列,表示“没有数据”)?
您使用外键默认值的好/坏经历是什么?
谢谢
答案 0 :(得分:8)
如果您将其标准化,则不会出现问题。
不要将国籍放在USER
表中,而是制作一个User_Nationality
表,将用户链接到另一个表中的Country_ID
。
如果他们在该查找表中有一个条目,那很好。如果没有,您不需要为其存储NULL
或默认值。
您需要强制执行FK关系,并允许NULL
违反该要求。您也不希望仅仅为填充字段而编制可能不准确的信息,从而否定了首先要求该字段的要点。
使用查找表,您可以完全绕过它。
这也可以让您改变主意,选择其中一个选项。
如果您使用视图,则可以选择将缺失数据视为NULL
或默认值,而无需更改基础数据。
答案 1 :(得分:3)
就个人而言,我觉得即使你的数据库中的非条目条目的键为-1,你仍然会检查是否要为每个条目显示“无数据”个别领域。
我会坚持使用NULL。 NULL意味着缺少数据,这就是这种情况。
答案 2 :(得分:1)
我喜欢你的B解决方案。也许可以将值映射到其他实体,因此你有Country,NullCountry扩展Country并映射到id = -1的行,并且在其方法中有特殊代码,以便于处理特殊情况。 / p>
一个问题可能是在外键上进行外连接会更难。
编辑:不,外连接应该没有问题,因为不需要进行外连接。
答案 3 :(得分:1)
B是一种可怕的方法。记住处理空值要比找出你使用的神奇数字更容易,然后你仍然需要处理它们。使用数字1.但我最喜欢JNK的想法。
答案 4 :(得分:1)
我建议选项D.如果并非所有用户都具有已定义的国籍,则该信息不属于用户表。创建一个名为UserNationality的表,键入UserId。