这是我的情况。我有一个表,其中列的值可以是 NULL、0 或另一个表中的值。另一个表的任何行都没有 0 值。
我最好的选择是什么?
1)不要添加FK。
2)向外表添加一条0记录。
3) 别的东西。
我无法将 0 值更改为空值。0 代表有效值。
谢谢您的帮助。
这是我的情况。我有一个表,其中列的值可以是 NULL、0 或另一个表中的值。另一个表的任何行都没有 0 值。
我最好的选择是什么?
1)不要添加FK。
2)向外表添加一条0记录。
3) 别的东西。
我无法将 0 值更改为空值。0 代表有效值。
谢谢您的帮助。
我个人会查看架构 - 此列是外键还是不是外键 - 听起来好像您正在尝试将该列用于 2 个不同的事物(“0 表示有效值”)。如果您无法更改架构以添加真正的 FK 列,那么将解决方案 1 作为次佳(IMO)
如果 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 上执行的以下语句。
带有 an 的检查约束EXISTS(SELECT 1 FROM OtherTable WHERE fkv=v) OR v=0
将是一个选项。但是,出于性能原因,始终首选真正的外键。(SQL Server 可以并且将在查询优化期间使用声明的外键关系,这通常会导致查询速度更快。)
此外,正如 Raphaël Althaus 所提到的,仅当您在子表中插入或更新记录时才会检查检查约束。即使有现有的子记录,删除父记录也不会产生任何后果。(为此,您可以添加一个触发器)
总而言之,添加“0”记录并声明真正的外键是您最好的选择。