Я бы задокументировал только известные отношения в таблице ссылок, которая связывает вашу таблицу 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
)
Возможно, вам понадобится ОБЪЕДИНИТЬ обратный запрос в зависимости от того, как вы хотите, чтобы ваши отношения были ограничены (братья и сестры всегда коммутативны, в отличие от других отношений), а затем аналогично обрабатывать матерей.