database-design - 对关系数据库中相同实体之间的多个多对多关系进行建模

标签 database-design relational-database data-modeling database-normalization

当两个表具有多对多关系或当一个表与自身具有多对多关系时,我们可以使用联结表对其进行建模。

然而,关系的类型可以超出原始类型,例如:

要求:我们有用户。每个用户可以有 0 个或多个其他用户作为 friend

解决方案:一个用户表和一个名为“user_user”的连接表。

然后我们发现了一个新要求:一些友谊是浪漫的,或者换句话说,两个用户可以以不同于友谊的方式联系。

  • 解决方案a:在联结表中增加一列,包含友谊类型( friend |合作伙伴|前 friend )等。
  • 解决方案 b:将 'user_user' 表重命名为 'friendships'(对于这种方法来说,这将是一个更好的名称)并创建一个名为 Romans 的新表,也将用户连接到用户。

  • 然后我们发现了另一个新要求:用户可以欠其他用户钱。同样,我们可以在同一个联结表上搭载或创建一个名为“债务”的新表。这次我的直觉是 100% 有一个单独的表。

    每次我们发现一种新的关系类型或已知关系的子类型时,我们都可以向一个连接表添加一列或创建一个新的连接表。

    我的问题是,决定何时必须创建新表的好规则是什么?

    是不是每个有序对必须多于一行?例如,如果过去的关系从未被删除,那么如果两个用户在过去两年内一直是 friend ,失去联系,然后重新成为 friend ,我们希望旧行也有开始和结束日期,但有两行使另一列信息重复(旧行显示用户欠钱,新行没有)。

    是不是当额外的列在逻辑上不是单一类型关系的定义时?

    OK:交友开始日期与交友1比1直接相关

    不正常:一个用户拥有另一个用户多少钱的列可以是 1 比 1 的关系,但逻辑上不是友谊的描述。

    如果我们事先知道两个表将有很多多对多的关系,是否有理由计划多个连接表或制作一个更灵活的单个连接表(即使连接类型是不是任意的)?

    最佳答案

    由你决定。您可以将“友谊”定义为与“浪漫参与”不同,因此需要两个连接表。或者您可以将“浪漫参与”定义为“友谊”的特例,因此需要一张 table 。我倾向于后者,因为后者更简单,更容易混淆。 (如果同样的两个人既是 friend 又是恋人呢?)

    但是,“欠钱”就不同了。如果A和B是 friend ,那么B就是A的 friend 。但是如果A欠B钱,说B欠A钱是错误的。哪个字段包含对 A 的引用,哪个包含对 B 的引用变得重要。为此,最好有一个单独的连接表。

    关于database-design - 对关系数据库中相同实体之间的多个多对多关系进行建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41079568/

    相关文章:

    sql - 有限制的多对多关系的数据库设计

    mysql 继承位置方案

    sql-server - 存储时间和星期几

    Python SQL 查询从关系数据库检索数据

    mysql - 如何使 MySQL RDS 仅对我的 IP 可用?

    python - 如何有效结合类设计和矩阵数学?

    mysql - 数据库表,越多越好?

    sql - 将表转换为第三范式

    mysql - 数据库设计 : save different details of payment (credit or check)

    database-design - 如何使用 MySQL 表表示规则?