【问题标题】:one to one relationship between 3 tables (back to back - 1 to 1 relationship)3个表之间的一对一关系(背靠背 - 1对1关系)
【发布时间】:2011-05-23 11:03:56
【问题描述】:

有 3 个表,即 FN、ADM、USR,代表一个 功能,该功能的管理员,参加该功能的用户。 管理员将是一个用户,而 ADM 必须从 USR 继承。
FN_I,USR_I 应该是 FN 和 USR 的主键。(这被许多其他表引用)
ADMN 是新添加的

我需要实现以下约束。
1.一个功能只能有一个管理员。(1-1)
2. 一个管理员只能管理一个功能。(1-0/1)

我尝试通过将 FN_ADM_I 设置为 FN_I 的外键来实现 1。
有人可以帮助我解决可以同时满足这两个要求的约束/关系吗?

【问题讨论】:

  • 你试过了,但是..发生了什么?你的结果是什么?什么有效,什么无效?
  • 只有一个管理员或一个用户(不能同时)管理一个功能?
  • @abatishchev:管理员继承自用户。所以基本上只有一个管理员可以管理一个功能。我提到管理员/用户的原因是我可以灵活地打破继承并将 USR 中的管理员特定字段保留为非管理员用户的 null。
  • 第一个要求是通过将 FN_ADM_I 设置为 FN_I 的外键来实现的。如何通过约束实现第二个要求?
  • 听起来这是一个背靠背、一对一的关系。

标签: sql sql-server tsql table-relationships


【解决方案1】:

您可能想要创建一个链接表:

FN_ADMIN_REL

FN_I, -- PK
ADMIN_I --PK 

其中两个字段都是具有唯一约束的主键:

ALTER TABLE FN_ADMIN_REL
ADD CONSTRAINT uc_Func_Admin UNIQUE (FN_I, ADMIN_I)

【讨论】:

  • 如果我有 FN_I 和 ADMIN_I 作为主键,那么字段的组合应该是一个主键,这意味着我可以将 (FN_I, ADMIN_I) 的值输入为 (1,2) ( 1,3) (1,5) 等等。这意味着 FN 1 有 3 个管理员。但我想要一个功能只有一个管理员,每个管理员只有一个功能。
  • @Raghav:那么你需要在两个字段上都使用 UNIQUE CONSTRAINT。
  • 您能告诉我如何在 Microsoft SQL Server 2008 中的两个字段上实现唯一约束
  • 感谢 abatishchev。有效。你说的是正确的。但请编辑 FN_I 的答案,--PK ADMIN_I --unique 约束.. 它可能对其他人有帮助。
【解决方案2】:

我认为您在这里混淆了术语。我认为 1-1(一对一)的关系并不是你想象的那样。

无论如何,如果我正确理解了您的问题(很可能并非如此),这就是您要做的。

  • 您已经有 FN 和 USR 表,每个表都有主键。
  • 逻辑上,参加功能的用户是多对多的关系:一个用户可以参加很多功能,每个功能可以有很多用户参加。多对多关系传统上由 sql server 中的“链接”表建模。您创建具有 FN_I 字段和 USR_I 字段的 FN_USR 表,并将这些外键分别设为 FN 和 USR。这就是您将功能与参与用户联系起来的方式。 (请注意,在您的图表上,这两个表之间没有关系,所以我只是猜测您想要多对多,您没有明确指定这一点。)
  • 现在让我们看看 ADM 表。这个是从USR“继承”的。在sql server中没有表继承的概念。这通常通过一对零或一关系建模。您创建 ADM 表并将主 ADM_I 设置为该表中的主键。您还可以使其成为 USR 表中 USR_I 列的外键。这就是管理员/用户关系的建模方式。每个管理员都是用户(每个 ADM 记录都有相关的 USR 记录)但不是每个用户都是管理员(不是每个 USR 记录都有相关的 ADM 记录)
  • 最后一部分是Admins和Functions之间的关系。由于没有管理员可以管理多个功能,因此这也是一对零或一。但是,在这种情况下,我们会将 ADM_I 列添加到 FUN 表中,并将其作为 ADM 表中 ADM_I 列的外键。这将给我们一对多。现在我们可以在 FUN 表中的 ADM_I 列上创建一个 UNIQUE 约束,以使这种关系成为一对零的关系。

这有意义吗?

【讨论】:

  • 1 和 2 都很好。现在问题出现在您解决方案的第三部分。这是现在的问题。当我将 FN 表的 ADM_I 作为 ADM 表的 ADM_I 的外键,并将 ADM_I 作为复合主键(与现有 FN_I 结合)时,我最终在 FN 表中有 2 个主键。这意味着,(FN_I, ADM_I) 是唯一的。所以它允许 (1,2) (1,3) 等。这意味着 FN_I 1 可以有 2 个管理员 - 2 和 3。但我想要的是一个 FN 应该只有一个管理员。
  • "并将 ADM_I 作为复合主键(与现有 FN_I 结合)"您为什么要这样做?只是不要这样做,你会没事的。您在这里不需要复合键。将 FN_I 保留为 FN 中的主键。对 FN 中的 ADM_I 进行唯一约束。从 FN 中的 ADM_I 到 ADM 中的 ADM_I 制作一个外键。我实际上只是重复了我在上面的答案中写的内容。你能解释一下不清楚的地方吗?
  • 是的,和你说的一样。其实我在想主键和唯一约束是一样的。现在实施并且工作正常。感谢您的解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-07-08
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 2021-04-14
  • 1970-01-01
  • 2021-02-01
相关资源
最近更新 更多