几个多对多关系到一张表
Posted
技术标签:
【中文标题】几个多对多关系到一张表【英文标题】:Several many-to-many relationships to one table 【发布时间】:2015-07-13 15:08:00 【问题描述】:我的数据库有几个类别,我想将用户创作的文本“注释”附加到这些类别中。例如,一个名为jobs
的高级表中的条目可能有一些用户写的关于它的注释,但sub_projects
中的一个较低级别的条目也可能如此。由于这些笔记都是相同的格式,我想知道我是否可以通过只有一个笔记表而不是像job_notes
或project_notes
这样的一系列表来简化事情,然后使用多个多对多关系以一次将其链接到其他几个表。
如果这不是从一开始就存在严重缺陷的想法(如果是,请告诉我!),我想知道最好的方法是什么。在我看来,我可以通过两种方式做到这一点:
-
为每个较大的类别(例如
job_notes_mapping
和 project_notes_mapping
)提供多对多连接表,并单独管理 MtM 关系
将单个联结表链接到 table_type
的枚举或单独的表,它指定 MtM 关系映射到哪个表:
+-------------+-------------+---------------+
| note_id | table_id | table_type_id |
+-------------+-------------+---------------+
| 1 | 1 | jobs |
| 2 | 2 | jobs |
| 3 | 1 | project |
| 4 | 2 | subproject |
| ........... | ........... | ........ |
+-------------+-------------+---------------+
如果这些想法中的任何一个是完全可怕的想法,请原谅我,但我认为这至少在概念上可能是一个有趣的问题。
【问题讨论】:
【参考方案1】:IMO 理想的方式是拥有工作、项目和子项目的超类型 - 我们称之为活动 - 您可以在其上定义任何常见的事实类型。
例如(我假设工作、项目和子项目形成一个包含层次结构):
activities (activity PK, activity_name, begin_date, ...)
jobs (job_activity PK/FK, ...)
projects (project_activity PK/FK, job_activity FK, ...)
subprojects (subproject_activity PK/FK, project_activity FK, ...)
不幸的是,大多数数据库模式为每个表定义了唯一的自动递增标识符,这使得在加载数据后实现超类型变得非常困难。 PostgreSQL 允许重用序列,这很好,其他一些 DBMS(如 mysql)根本无法做到这一点。
我的第二个选择是您的选项 1,因为它允许定义外键约束。我根本不喜欢选项 2。
【讨论】:
如果有人想知道我的示例中的列命名约定,它是 role_domain 而不是 table_id。 不幸的是,第二次看这个答案实际上不是我想要的。由于活动将通过外键引用,因此不再是多对多关系 - 您只能为一项工作拥有一个活动条目。就我的 Notes 而言,我希望有多个注释来描述一个工作/项目/子项目。 我的目标是超类型作业、项目和子项目,以便可以使用活动和注释之间的多对多映射,而不是每个级别的单独映射。我没有建议活动来代替笔记。 所以你描述的是一个系统,它去job->activity<-activity_note_mapping->notes
?你能描述一下你创建条目的顺序,以及它与你描述的超类型问题的关系吗?
在我的建议中,每个工作(以及项目和子项目)都是一个活动,因此您可以直接将工作加入到 activity_note_mapping 中。如果作业、项目和子项目的 id 重叠,则可以改为为它们每个添加一个 activity_id,但这不再理想。【参考方案2】:
不幸的是,我们最终得到了最丑陋的答案,即为每种不同类型的条目(job_notes、project_notes 和 subproject_notes)都有一个注释表。我们这样做的原因如下:
具有包含联结“类型”列的单个联结表性能较差,因为没有一个外键是“真实的”并且必须手动搜索。注释字段包含每个条目的大量文本这一事实使情况更加复杂。
每个条目的联结表增加了一个额外的表,而不是简单地为每种表类型设置单独的注释表,虽然它看起来稍微漂亮一些,但它并没有带来实质性的性能提升。
我对这个答案不满意,因为为正在描述的每个作业/项目/子项目表有效地复制同一个 Notes 表似乎太浪费了。但是,我们还没有找到一个能够长期保持性能的答案。如果有人对如何执行此操作有更好的建议,我会保持打开状态!
【讨论】:
以上是关于几个多对多关系到一张表的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server Analysis Services 中的多对多关系;第二个多对多关系不起作用