many-to-many - 有一张人表,我想将他们相互链接,多对多,链接是双向的

标签 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 |
+-------------------------------+

这些人需要协作/工作,所以你有一个链接表,将一个人的记录链接到另一个人:
create table person__person (
    person__person_id int,
    person_id int,
    other_person_id int
)

这种设置意味着人与人之间的链接是单向的——即 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 |
+---------------------+-----------+--------------------+

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

我意识到我可以做联合和不同的查询,以及在 UI 中将关系呈现为相互关系,但有没有更好的方法?我有一种感觉,有一种更好的方法,通过正确设置数据库,这个问题可以巧妙地消失,但我看不到它。有人有更好的主意吗?

最佳答案

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

自从你们的关系表可以 表示单向关系,我建议这样对待它们。换句话说,对于每个关系,我会添加两行。如果 Alice 与 Bob 合作,表格应该如下:

select * from person__person;
+---------------------+-----------+--------------------+
|   person__person_id | person_id |    other_person_id |
+---------------------+-----------+--------------------+
|                   1 |         1 |                  2 |
|                   2 |         2 |                  1 |
+---------------------+-----------+--------------------+

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

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

关于many-to-many - 有一张人表,我想将他们相互链接,多对多,链接是双向的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2879773/

相关文章:

MongoDB,文档或集合之间的关系

mysql - Mysql 中 count() 的不等式

java - Spring + hibernate DAO : get method for many-to-many

database-design - 通用数据模型设计模式的任何资源?

database - 使用 "real"数据库建模工具有什么意义?

ios - 哪种数据模型最适合存储 Instagram 之类的数据?

python - Django 双向 ManyToMany - 如何防止在第二个模型上创建表?

C# Nhibernate - 向多对多关系添加新项目

statistics - 寻找一种简单的机器学习方法来从训练集中预测期末考试成绩

database - 如何在数据库中对此[网络,帖子中的详细信息]进行建模以提高效率和易用性?