IDEA A不会强制ProfileA
.
假设不是 NULL, IDEA BUser.ProfileAId
可以,但这引入了只能通过延迟约束(MS SQL Server 不支持)解决的循环 FK。除此之外,您还需要一个 UNIQUE 约束User.ProfileBId
来防止不同的用户共享相同的ProfileB
内容(这需要额外的索引,并且每个新索引都会带来一定的开销,特别是如果您打算使用集群)。
由于我们正在处理“1:1”(User
: ProfileA
)和“1:0 或 1”(User
: ProfileB
)关系,我可能只是将所有内容放在同一个表中,然后使用 NOT NULL 与 NULL 约束来要求ProfileA
与。只是允许ProfileB
。
User
------------------
UserID PK
ProfileARequiredField1 NOT NULL
ProfileARequiredField2 NOT NULL
ProfileARequiredField3 NOT NULL (...)
ProfileAOptionalField1 NULL
ProfileAOptionalField2 NULL
ProfileAOptionalField3 NULL (...)
ProfileBRequiredField1 NULL
ProfileBRequiredField2 NULL
ProfileBRequiredField3 NULL (...)
ProfileBOptionalField1 NULL
ProfileBOptionalField2 NULL
ProfileBOptionalField3 NULL (...)
-- For ProfileB, if one required field is present, all must be present,
-- and optional fields are allowed only if required ones are present.
CHECK (
(
ProfileBRequiredField1 IS NULL AND
ProfileBRequiredField2 IS NULL AND
ProfileBRequiredField3 IS NULL AND
ProfileBOptionalField1 IS NULL AND
ProfileBOptionalField2 IS NULL AND
ProfileBOptionalField3 IS NULL
)
OR (
ProfileBRequiredField1 IS NOT NULL AND
ProfileBRequiredField2 IS NOT NULL AND
ProfileBRequiredField3 IS NOT NULL
)
)
或者,将ProfileA
字段保留在 中User
,但将ProfileB
字段移动到单独的表中,就像您在 IDEA A 中所做的那样(不需要 IDEA B 的复杂性)。但是,NULL 存储很便宜,您可以使用过滤索引从索引中排除 NULL,因此这可能不值得。