我需要在表中添加一个外键。
随着每条记录的修改,用户最终会添加列值。
所以我创建了一个FK约束with NOCHECK
。但该列不能为空,因此我将其声明为NOT NULL
。 SQL Server不允许我在可以为空的列上执行此操作,它必须具有值或默认值。
如何创建一个首先没有条目但是应该修改的FK必须提供密钥值?
答案 0 :(得分:1)
听起来你有一个可选的关系 - 将FK建模为NULLable,同时仍然强制执行约束是一种常见的方法(NDB FK' s将不会被RDBMS检查)。例如在下面,我们有一个Person
表,但最初在Person捕获期间,我们不知道用户所在的城市,所以我们使CityId
外键可以为空:
CREATE TABLE City
(
CityId INT NOT NULL PRIMARY KEY,
Name NVARCHAR(200)
);
CREATE TABLE Person
(
PersonId INT NOT NULL PRIMARY KEY,
CityId INT NULL, -- Nullable
Name NVARCHAR(200),
CONSTRAINT FK_PersonCity FOREIGN KEY(CityID) REFERENCES City(CityID)
);
Person
现在允许CityID为NULL(表示未知),或者如果为非null,则CityID必须有效且存在于City
中。唯一的问题是'这里是你需要LEFT OUTER JOIN
人回城去考虑城市未知的人。
我见过的另一个策略是在主表中添加DUMMY行(例如City(ID = 0, Name = 'Unknown')
,然后将其用作外键的默认值 - 它将保证INNER JOIN
。< / p>
如果您需要强制要求在以后的步骤中外键(城市分类)成为强制性要求,我建议您在业务逻辑中执行此操作 - 在代码中或从存储过程中执行此操作。
答案 1 :(得分:0)
将列添加到现有表时,将使用NULL
值创建新列。因此,除非您还指定了默认值,否则无法向表中添加not null
列。在这种情况下,新字段将包含默认值。
如果您想添加一个强制性FK的新列,您实际上只有两个选项:
not null
。not null
。第一个选项的优点是你不会长时间持有桌子上的锁。缺点是可能需要数周或数月才能最终填满每一行。
第二个选项的优点是可以非常快速地创建和填充该字段,并且所有字段都可以放在一个事务中。缺点是您在整个表中锁定持续时间。首先获取锁定可能非常困难,而且您的DBA可能会有几个关于锁定它的选择词超过几秒钟。
获取上述DBA并确定哪种方式最适合您的特定情况。