简体   繁体   English

与一个表的几个多对多关系

[英]Several many-to-many relationships to one table

My database has several categories to which I want to attach user-authored text "notes". 我的数据库有几个类别,我想将用户创作的文本“注释”附加到其中。 For instance, an entry in a high level table named jobs may have several notes written by the user about it, but so might a lower level entry in sub_projects . 例如,一个名为jobs高级表中的条目可能由用户编写了一些有关它的注释,但是sub_projects一个较低级的条目也可能有sub_projects Since these notes would all be of the same format, I'm wondering if I could simplify things by having only one notes table rather than a series of tables like job_notes or project_notes , and then use multiple many-to-many relationships to link it to several other tables at once. 由于这些注释的格式都相同,所以我想知道是否可以通过仅具有一个注释表而不是像job_notesproject_notes类的一系列表来简化事情,然后使用多个多对多关系将其链接一次转到其他几个表。

If this isn't a deeply flawed idea from the get go (let me know if it is!), I'm wondering what the best way to do this might be. 如果这不是一开始就存在的严重缺陷的想法(请让我知道它是否是!),我想知道这样做的最佳方法是什么。 As I see it, I could do it in two ways: 如我所见,我可以通过两种方式做到这一点:

  1. Have a many-to-many junction table for each larger category, like job_notes_mapping and project_notes_mapping , and manage the MtM relationships individually 每个较大的类别都有一个多对多联结表,例如job_notes_mappingproject_notes_mapping ,并分别管理MtM关系
  2. Have a single junction table linked to either an enum or separate table for table_type , which specifies what table the MtM relationship is mapping to: 将单个联结表链接到table_type的枚举表或单独的表,该表指定MtM关系映射到的表:

     +-------------+-------------+---------------+ | note_id | table_id | table_type_id | +-------------+-------------+---------------+ | 1 | 1 | jobs | | 2 | 2 | jobs | | 3 | 1 | project | | 4 | 2 | subproject | | ........... | ........... | ........ | +-------------+-------------+---------------+ 

Forgive me if any of these are completely horrible ideas, but I thought it might be an interesting question at least conceptually. 如果其中任何一个都是完全可怕的想法,请原谅我,但我认为,至少从概念上讲,这可能是一个有趣的问题。

The ideal way, IMO, would be to have a supertype of jobs, projects and subprojects - let's call it activities - on which you could define any common fact types. IMO的理想方法是拥有作业,项目和子项目的超类型(我们称之为活动),您可以在其上定义任何常见的事实类型。

For example (I'm assuming jobs, projects and subprojects form a containment hierarchy): 例如(我假设工作,项目和子项目构成一个容纳层次结构):

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, ...)

Unfortunately, most database schemas define unique auto-incrementing identifiers PER TABLE which makes it very difficult to implement supertyping after data has been loaded. 不幸的是,大多数数据库模式都定义了唯一的自动递增标识符PER TABLE,这使得在加载数据后很难实现超类型化。 PostgreSQL allows sequences to be reused, which is great, some other DBMSs (like MySQL) don't make it easy at all. PostgreSQL允许重用序列,这很棒,其他一些DBMS(如MySQL)根本不容易。

My second choice would be your option 1, since it allows foreign key constraints to be defined. 我的第二个选择是您的选项1,因为它允许定义外键约束。 I don't like option 2 at all. 我根本不喜欢选项2。

Unfortunately, we have ended up going with the ugliest answer to this, which is to have a notes table for every different type of entry - job_notes, project_notes, and subproject_notes. 不幸的是,我们最终得到了最丑陋的答案,那就是为每种不同类型的条目(job_notes,project_notes和subproject_notes)创建一个注释表。 Our reasons for this were as follows: 我们这样做的原因如下:

  • A single junction table with a column containing the "type" of junction has poor performance since none of the foreign keys are "real" and must be manually searched. 具有一个包含联结的“类型”列的单个联结表的性能很差,因为外键都不是“真实”的,因此必须手动搜索。 This is compounded by the fact that the Notes field contains a lot of text per entry. 注释字段在每个条目中包含很多文本的事实使情况更加复杂。

  • A junction table per entry adds an additional table over simply having separate notes tables for every table type, and while it seems slightly prettier, it does not create substantial performance gains. 每个条目的联结表在为每种表类型仅具有单独的注释表的基础上增加了一个附加表,虽然它看上去稍微漂亮一些,但并不能带来实质的性能提升。

I'm not satisfied with this answer, because it seems so wasteful to effectively be duplicating the same Notes table for every job/project/subproject table that is being described. 我对这个答案不满意,因为为正在描述的每个作业/项目/子项目表有效地复制相同的Notes表似乎太浪费了。 However, we haven't been able to come up with an answer that would hold up performance wise in the long term. 但是,从长远来看,我们还没有找到一个可以提高性能的答案。 I'll leave this open in case anyone has better recommendations for how to do this! 如果有人对如何执行此操作有更好的建议,我将保持开放状态!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM