如何在 M:M 中强制执行 1:M 关系?

Posted

技术标签:

【中文标题】如何在 M:M 中强制执行 1:M 关系?【英文标题】:How to enforce a 1:M relation in a M:M? 【发布时间】:2022-01-04 19:29:42 【问题描述】:

我正在设计一个数据库架构。

目前有2张桌子:

    任务(TaskID、TaskName) 描述(DescriptionID、描述)

一个任务可以有多个描述,但同一个描述不应该被多个任务共享。描述可以有 0 或 1 个任务(用户应该能够在没有任务的情况下添加描述,并且以后能够链接任务)。

选项 1:

在 Description 表中添加 TaskID 作为可为空的外键。

选项 2

相反,我可以创建另一个名为 TaskDescription(RowID, TaskID, DescriptionID) 的表。 但现在是 M:M。一个任务可以有多个描述,一个描述可以被多个任务共享。在这种情况下,如何防止多个任务共享相同的描述?

【问题讨论】:

在选项 2 中,您可以创建独立于任务的描述,即使该任务不存在。这有意义吗?使用 OPT 1 all columns NOT NULL 这使得描述可选。也不要忘记 Description_Text 上的 UNIQUE。 选项 1 还允许通过使外键为空来创建独立于任务的描述。 你好在吗? 【参考方案1】:

选项 2

相反,我可以创建另一个名为 TaskDescription(RowID, TaskID, DescriptionID) 的表。但它现在是 M:M。一个任务可以有多个描述,一个描述可以被多个任务共享。在这种情况下,如何防止多个任务共享相同的描述?

只有具有复合主键的两列(显然在两列上)就足够了另一个表,以及descriptionID 上的唯一索引,这将强制

但同一描述不应被多个任务共享

类似这样的东西(Oracle 语法;忽略它。我希望通过查看一些代码而不是阅读我的非英语母语描述更容易理解我的意思):

create table taskDescription
  (taskID         number  constraint fk_td_task references task (task_id),
   descriptionID  number  constriant fk_td_desc references description (descriptionID),
  --
  constraint pk_td primary key (taskID, descriptionID)
  );

create unique index ui1_td on taskDescription (descriptionID);

这样做,如果您尝试违反任何强制约束,数据库将处理所有内容并引发错误。

【讨论】:

以上是关于如何在 M:M 中强制执行 1:M 关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 postgresql 中强制删除索引关系?

如何使用 ef 对迁移构建强制执行 Restrict DeleteBehavior?

Vim 中如何去掉 ^M 字符

如何在 Entity Framework 中强制沿导航关系进行完整加载?

在纱线工作区中,如何强制解决子项目的依赖关系?

Python语言之如何实现约瑟夫环问题