在关系数据库中建模存在事实

时间:2010-01-07 22:01:05

标签: sql sql-server database-design

我需要一种在数据库中表示存在关系的方法。例如,我有一个生物历史表(即家谱),它存储父ID和子ID,它们是人员表的外键。该表用于描述任意的家庭关系。因此,我希望能够说X和Y是兄弟姐妹,而不必确切地知道X和Y的父母是谁。我只想说能有两个不同的人A和B,A和B分别是X和Y的父母。一旦我知道A和/或B是谁,我需要能够调和他们。

我能想到的最简单的解决方案是使用负整数用户ID存储存在的人。一旦我知道了这些人是谁,我就需要级联更新所有ID。有没有任何众所周知的技术?

3 个答案:

答案 0 :(得分:1)

存在主义意味着“不存在”吗?

他们不一定是消极的。你可以在People表中添加一条没有姓/名的记录,也许还有一个标志“未知的人”。如果你愿意,可以存在。

然后,当您知道某些事情(例如姓氏但不是第一个)时,您需要更新此记录。

协调重复的人可能会更困难。我想你可以只更新FamilyTree set parent_id = new_id where parent_id = old_id等等。但是这意味着同一个人可能最终会有太多的父母,所以你需要在执行之前执行一些复杂的检查

答案 1 :(得分:1)

我只记录链接表中的已知关系,该链接表将您的Person表与其自身链接:

FK Person1ID
FK Person2ID
   RelationshipTypeID (Sibling, Father, Mother, Step-Father, Step-Mother, etc.)

对该表有一些适当的约束(或多个表,每个关系类型一个,如果这使得约束更合乎逻辑)

然后当其他关系可以可能(半兄弟只会共享一个父级)被推断(通过运行异常查询)但是缺少时,创建它们。

例如,那些兄弟姐妹没有找到所有父母的人:

SELECT *
FROM People p1
INNER JOIN Relationship r_sibling
    ON r_sibling.Person1ID = p1.PersonID
    AND r_sibling.RelationshipType = SIBLING_TYPE_CONSTANT
INNER JOIN People p2
    ON r_sibling.Person2ID = p2.PersonID
WHERE EXISTS (
    -- p1 has a father
    SELECT *
    FROM Relationship r_father
        ON r_father.RelationshipType = FATHER_TYPE_CONSTANT
        AND r_father.Person2ID = p1.PersonID
)
AND NOT EXISTS (
    -- p2 (p1's sibling) doesn't have a father yet
    SELECT *
    FROM Relationship r_father
        ON r_father.RelationshipType = FATHER_TYPE_CONSTANT
        AND r_father.Person2ID = p2.PersonID
)

您可能需要UNION与此查询相反,具体取决于您希望关系如何受限(兄弟姐妹总是可交换的,与其他关系不同),然后同样处理母亲。

答案 2 :(得分:0)

嗯,来想一想,我想无论如何我需要一种调和重复人的一般方法,我可以将它用于此目的。想法?