我需要为用户和关联的个人资料建立一个场景模型。
要求:
用户必须拥有必填个人资料(ProfileA),用户才能可选拥有商家资料(ProfileB)。
用户每个配置文件类型只能关联1个配置文件。
这里有关于DataBase设计的想法,我很乐意在Idea B中使用Nullable FK,提出您的意见和想法。
如果您还有替代建模解决方案,请与我分享。提前谢谢。
IDEA A:
Users
------------------
UserID PK
ProfilesA
------------------
UserID PK FK
ProfilesB
------------------
UserID PK FK
IDEA B(使用Nullable FK):
Users
------------------
UserID PK
ProfileAId NULL FK
ProfileBId NULL FK
ProfilesA
------------------
ProfileAId PK
ProfilesB
------------------
ProfileBId PK FK
答案 0 :(得分:1)
IDEA A 不会强制执行ProfileA
。
IDEA B 可以,假设User.ProfileAId
为非NULL,但这会引入循环FK,只能解决延迟约束(MS SQL Server不支持)。除此之外,您还需要User.ProfileBId
上的UNIQUE约束,以防止不同用户共享相同的ProfileB
(这需要额外的索引,并且每个新索引都会产生一定的开销,特别是如果您打算使用clustering)。
由于我们处理的是“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存储很便宜,您可以使用filtered indexes从索引中排除NULL,因此这可能不值得。