【问题标题】:Relational design - one "many to many" and two "one to many" "between" two tables关系设计 - 一个“多对多”和两个“一对多”“在”两个表之间
【发布时间】:2014-06-16 07:06:20
【问题描述】:

我有以下(简化的)应用程序要求,我需要在 SQL Server 中创建数据库:

  • 实体 A 与实体 B 存在多对多关系
  • 实体 A 与实体 C 存在一对多关系
  • 实体 B 也与实体 C 存在一对多关系。

我使用以下表格对此进行了建模:

一个(PK)

B (b PK)

A_B(a FK A(a), b FK B(b), PK(a,b))

C (c PK, a FK A(a), b FK B(b))

观察。从(扩展的)规范中:A_B 中可以有一对 (a,b),而 C 中不存在。

  1. 这是一个好的设计吗?我在问,因为显然您可以在表 C 中插入一对 (a,b),而表 C 中不存在表 A_B,后者负责将 As 关联到 Bs。

  2. 可以在 C 上创建一个触发器来执行上述检查,但此解决方案将处于实现级别。

  3. 另一种选择是在 C 中的 (a,b) 上创建复合 FK。我以前从未使用过它们,所以我的问题再次是这样继续是否可以。

感谢任何提示!

【问题讨论】:

  • 我认为你在抽象问题方面走得太远了。您不能问 us 是否可以在 C 中拥有 A_B 中不存在的条目是否是一个问题,这似乎是您在问题 1 中要问的问题。如果您的问题(正如 2 和 3 似乎指向的那样)是您如何防止这种情况,那么是的,3 似乎是正确的选择。
  • C 中的条目在 A_B 中不存在肯定是个问题。现在重读1,我意识到这是模棱两可的。我的预期问题是:鉴于您不应该在 C 中添加一个条目 (a,b),而 A_B 中不存在对应的条目,那么正确的设计是什么?据我了解,(a,b)上的 C 中的 FK 似乎是正确的选择。谢谢!我看不到如何将您的评论标记为答案。

标签: sql-server relational


【解决方案1】:

是的,从 CA_B 的外键将阻止出现在 C 中的条目出现在 A_B 中。比如:

 CREATE TABLE A (a char(3) not null, constraint PK_A PRIMARY KEY (a));

 CREATE TABLE B (b char(7) not null, constraint PK_B PRIMARY KEY (b));

 CREATE TABLE A_B(
    a char(3) not null,
    b char(7) not null,
    constraint PK_A_B PRIMARY KEY(a,b),
    constraint FK_A_B_A FOREIGN KEY (a) REFERENCES A(a),
    constraint FK_A_B_B FOREIGN KEY (b) REFERENCES B(b)
 );

 CREATE TABLE C (
    c char(19) not null,
    a char(3) not null,
    b char(7) not null,
    constraint PK_C PRIMARY KEY (c),
    constraint FK_C_A FOREIGN KEY (a) REFERENCES A(a),
    constraint FK_C_B FOREIGN KEY (b) REFERENCES B(b),
    constraint FK_C_A_B FOREIGN KEY (a,b) REFERENCES A_B(a,b)
 );

您是否继续拥有FK_C_AFK_C_B 取决于您。在上面的模型中,它们是多余的,但是如果,例如,a 和/或C 中的b 可以为空,那么当值不是全部时,将它们分开以强制执行外键是有意义的非NULL

【讨论】:

    【解决方案2】:

    只需在 sql 中使用 join 即可:

      select A.*, B.*, C1.*, C2.* from A 
        left outer join B on A.id=B.id
        left outer join C as C1 on A.id=C1.id
        left outer join C as C2 on B.id=C2.id
        -- Where condition as per requirement
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多