我有一个不常见的数据库设计问题我不确定如何正确处理。有一个名为profile
的表存储网站用户的公开个人资料信息。但是,每个配置文件都可以属于一个人或一对,所以我需要一个名为person
的附加子表来存储特定于人的数据。每个profile
实体必须至少有一个但不超过两个person
子实体。
建立这种关系的最佳方式(就“犹太教”和/或表现而言)是什么?我应该使用常规的一对多并以编程方式或使用存储过程强制执行子项数量吗?或者我应该只在父表中创建两个外键字段,并允许null
为其中一个?也许还有另一种我无法想到的方式?
修改:回应戈登问题的其他信息
person
令人困惑,因为它可能表明一个人有个人资料,而实际上这是个人信息的个人资料。答案 0 :(得分:3)
有两个字段的解决方案:
但是如果你愿意在应用程序级别强制执行最小数字,那么最好用这样的东西:
CHECK(PERSON_NO = 1 OR PERSON_NO = 2)
特性:
另一方面,如果你有一个密钥PERSON_ID(或类似的),那么{PROFILE_ID,PERSON_NO}上的附加索引也是有效执行这些字段上的密钥约束所必需的。
从理论上讲,您甚至可以将这两种方法结合起来,避免 无人简介的人和无人简介:
(PERSON1_ID不能为空,PERSON2_ID可以为空)
然而,这会导致循环引用,需要延迟约束来解析,遗憾的是MySQL不支持这些约束。
最后,您可以采用蛮力方法,只需将两个人的字段放在配置文件表中(并使其中一个集合不能为NULL,另一个为NULL)。
在所有这些可能性中,我可能会选择2)。
答案 1 :(得分:1)
正如您在问题中提到的,您基本上有两个选项。您可以在表中存储两个字段。或者,您可以拥有第二个包含映射信息的表。
以下是一些可以帮助您回答问题的其他问题:
在这种情况下,我只是狡猾地怀疑“2”的限制将来可能会改变。这表明将映射存储在单独的表中,因为通过添加字段来增加“2”在修改现有代码方面是个问题。换句话说,创建一个单独的表,person-profile,将人员映射到配置文件。在mysql中,您始终可以使用GROUP_CONCAT()收集人员级别的信息。
最好将这样的相似字段放在同一个表中的情况是一个明显优先,另一个是备用。在这种情况下,你正在做很多“合并(,)”类型的逻辑。