如何使用1个记录存储家庭关系信息

6
考虑我们有一个人A。F是他的父亲,M是他的母亲,B是他的兄弟,S是他的儿子。每个人都可能有许多关系。因此,我们需要创建以下新的关系表:
人们
+----+------+
| id | name |
+----+------+
| 1  | A    |
| 2  | F    |
| 3  | M    |
| 4  | B    |
| 5  | S    |
+----+------+

关系类型
+----+---------+
| id | value   |
+----+---------+
| 1  | Father  |
| 2  | Mother  |
| 3  | Brother |
| 4  | Son     |
| 5  | Wife    |
| 6  | Husband |
+----+---------+

关系
+----+----------+------------+------+
| id | PersonID | RelativeID | Type |
+----+----------+------------+------+
| 1  | 1        | 2          | 1    |
| 2  | 1        | 3          | 2    |
| 3  | 1        | 4          | 3    |
| 4  | 1        | 5          | 4    |
| 5  | 2        | 1          | 4    |
| 6  | 2        | 3          | 5    |
| 7  | 3        | 1          | 4    |
| ......                            |
+----+----------+------------+------+

在这种情况下,第一行表示2是1的父亲(对于ID),第五行表示1是2的儿子。在现实世界中,这两行是等价的,但如果我不插入其中一行,则无法使用现有行获取缺失行的含义。
问题是:如何使结构包含这两个含义在一行中?

有点离题(不是回答你的问题),但我建议保留现有的设计。如果您开始对PersonID和RelativeID进行“对称”使用,那么所有查询都会变得更加复杂(或更慢)。此外,您的数据可能会有一些未来的扩展(例如与许多参与者相关的事件),当您需要三个或更多相关人员时 - 在您当前的设计中,这将不是问题。您可以使用触发器同步双重记录。 - Arvo
1
猜测relationship(id, personA, personB, AtoB_type,BtoA_type)可以有所帮助吗? - amow
1个回答

3
实际上,在两个亲戚之间,我们有两种关系:
Person A is person B`s wife <=> Person B is person A`s husband
Person C is person D`s sister <=>Person D is person C`s brother (D is male)
Etc...

如果你在第三个表格(关系)中提供一个Reverse_Relation_Type列,那么你的问题就会得到解决,而且你将不会有任何冗余数据,你将拥有:

+----+----------+------------+---------------+-----------------------+
| id | PersonID | RelativeID | Relation_Type | Reverse_Relation_Type |
+----+----------+------------+---------------+-----------------------+
| 1  | 1        | 2          | 1             |4                      |
| 2  | 1        | 3          | 2             |4                      |
| 3  | 1        | 4          | 3             |3                      |
| 4  | 1        | 5          | 4             |6                      |
| 6  | 2        | 3          | 5             |1                      |
| ......                                                             |
+----+----------+------------+---------------+-----------------------+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接