最自然的方式来建模几个多对多关系

时间:2012-08-30 22:00:06

标签: database database-design

让我们说我有书和人。一个人可以创作很多书,一本书可以由很多人创作。一个人读了很多书,很多人都读过一本书。

Person               Book
------               -----
personId             bookId

我可以使用两个关系表:

has_read             has_authored
--------             ------------
personId, bookId     personId, bookId

或者一个:

person_book_relation
--------------------
personId, bookId, relationType ("read", "authored")

另一个例子可能是Actor和Event之间的某种订阅者/发布者关系。

有没有可供选择的指导方针?

如果有更多类型的关系怎么办?这会改变你的解决方案吗?

团队中有许多人有角色。一个人可以在很多团队中。 (只是这样做)

Team_Person_relation
--------------------
TeamId, PersonId, Role ('Defender', 'Attacker', 'Goalkeeper', 'Midfielder'... etc)

如果你使用单独的表,这至少是4个表。但是,有点像团队角色比“阅读/撰写”关系更能相互联系?

2 个答案:

答案 0 :(得分:3)

我会使用第二种类型的表,除非遇到关系类型实际影响表中列的情况。

例如,在书籍示例中,作者可能有一个日期,他们将日期发送给出版商,这使得将所有信息保存在一个表格中的想法无效,因为该信息不适用于读者

同样地,“目标已保存”只适用于你的守门员。

我认为诚实的,如果有点陈腐的反应是“它取决于你要提取的信息” - 但一般来说,你可以更明确地表明“这是描述表格x和表格y之间关系的表格” “将更清晰,更容易维护您的数据库。

答案 1 :(得分:1)

作为数据库创建者,它主要取决于您,因为两种解决方案都是正确的。应该考虑的主要是如何在未来使用数据(或至少现在预测将如何使用)。一些例子:

  1. 如果你在一个表中强制使用太多的多对多关系,那么在使用其中一个表时,你需要始终记住“那里有其他关系”。例如,如果您希望查看所有未编写任何书籍的人,则需要以某种方式构建左连接查询,以过滤“读取”关系。随着查询变得越来越复杂,包含更多表和更多外连接,很容易得到不需要的结果。

  2. 团队角色的示例表明,角色列表将来可能会发生变化。因此,将此角色保留在关系专栏中是更好的解决方案。此外,这种关系在这里指的是“作为一个团队的成员”,这个成员的角色只是这个会员的财产。

  3. 如果您希望存储一些与您的多对多关系的附加信息(例如创作日期,或读者喜欢这本书的数量),它会建议单独的表,否则许多稀疏列将是用来处理所有可能的关系。

  4. 最后但并非最不重要:表现。如果表格试图包含太多“不相关”的数据,有时可能很难有效地设计和使用索引。