这是我的情况。我有一个表,其中列的值可以是NULL,0,或来自anther表的值。另一个表的任何行都没有0值。
我最好的选择是什么?
1)不要添加FK。
2)将0记录添加到外表。
3)别的东西。
我无法将0值更改为null。 0表示有效值。
感谢您的帮助。
答案 0 :(得分:1)
我个人会看一下这个模式 - 这个列是外键还是不是 - 听起来好像你正试图将这个列用于两个不同的东西(“0代表一个有效的值”)。 如果您无法更改架构以添加真正的FK列,那么请使用解决方案1作为下一个最佳(IMO)
答案 1 :(得分:0)
如果0是有效值,我个人会将0添加为“外国表”的记录。
或3)使用CHECK CONSTRAINT而不是FOREIGN KEY。
但答案不能是1)或2)或3)作为“最佳实践通用答案”:它取决于您的需求(当您的表中的某些内容在外表中删除时必须发生的事情是最重要的考虑因素之一。)
检查限制的弱点:
http://msdn.microsoft.com/en-us/library/ms188258(v=sql.105).aspx
在DELETE语句期间不验证CHECK约束。 因此,对具有某些类型的表执行DELETE语句 检查约束可能会产生意外结果。例如, 考虑在表CheckTbl上执行以下语句。
答案 2 :(得分:0)
使用EXISTS(SELECT 1 FROM OtherTable WHERE fkv=v) OR v=0
的检查约束是一种选择。但是,出于性能原因,始终首选真正的外键。 (SQL Server可以并且将在查询优化期间使用声明的外键关系,这通常会导致更快的查询。)
此外,正如RaphaëlAlthaus所述,只有在子表中插入或更新记录时才会检查检查约束。即使有现有的孩子,删除父记录也没有后果。 (为此你可以添加一个触发器)
总而言之,添加“0”记录并声明真正的外键是最好的选择。