有一个人的表,我想链接到彼此,多对多,链接是双向的

Dun*_*ock 6 many-to-many data-modeling

想象一下,你生活在一个非常简单的例子中 - 想象一下你的MySQL数据库中有一个人员表:

create table person (
    person_id int,
    name text
)

select * from person;

+-------------------------------+
|   person_id |            name |
+-------------------------------+
|           1 |           Alice |
|           2 |             Bob |
|           3 |           Carol |
+-------------------------------+
Run Code Online (Sandbox Code Playgroud)

这些人需要协作/一起工作,所以你有一个链接表,将一个人的记录链接到另一个人:

create table person__person (
    person__person_id int,
    person_id int,
    other_person_id int
)
Run Code Online (Sandbox Code Playgroud)

这种设置意味着人们之间的链接是单向的 - 即Alice可以链接到Bob,而Bob没有链接到Alice,更糟糕的是,Alice可以链接到Bob , Bob可以同时链接到Alice,在两个单独的链接记录中.由于这些链接代表了工作关系,在现实世界中它们都是双向的相互关系.以下是此设置中的所有内容:

select * from person__person;

+---------------------+-----------+--------------------+
|   person__person_id | person_id |    other_person_id |
+---------------------+-----------+--------------------+
|                   1 |         1 |                  2 |
|                   2 |         2 |                  1 |
|                   3 |         2 |                  2 |
|                   4 |         3 |                  1 |
+---------------------+-----------+--------------------+
Run Code Online (Sandbox Code Playgroud)

例如,上面的person__person_id = 4,当你查看Carol的(person_id = 3)个人资料时,你应该看到与Alice的关系(person_id = 1),当你查看Alice的个人资料时,你应该看到与Carol的关系,即使链接走另一条路.

我意识到我可以做联合和不同的查询,以及在UI中将关系呈现为相互关系,但是有更好的方法吗?我有一种感觉,有一个更好的办法,一个地方这个问题将整齐正确设置数据库融化了,但我无法看到它.谁有更好的主意?

sha*_*nan 3

我不确定是否有更好的方法来配置您的表。我认为你拥有它们的方式是正确的,也是我实施它的方式。

由于您的关系表可以指示单向关系,因此我建议如此对待它们。换句话说,对于每个关系,我都会添加两行。如果 Alice 与 Bob 合作,则该表应如下所示:

select * from person__person;
+---------------------+-----------+--------------------+
|   person__person_id | person_id |    other_person_id |
+---------------------+-----------+--------------------+
|                   1 |         1 |                  2 |
|                   2 |         2 |                  1 |
+---------------------+-----------+--------------------+
Run Code Online (Sandbox Code Playgroud)

原因是因为在很多 ActiveRecord (Rails) 之类的系统中,多对多表对象不够智能,无法同时查询 person_id 和 other_person_id。通过保留两行,ActiveRecord 之类的对象将正常工作。

然后您应该做的是在代码级别强制执行数据的完整性。每次在两个用户之间建立关系时,都应插入两条记录。当关系被破坏时,两条记录都应该被删除。不应允许用户与自己建立关系。