【问题标题】:How to map multiple foreign key from ER model to relational model?如何将多个外键从 ER 模型映射到关系模型?
【发布时间】:2012-02-16 08:23:21
【问题描述】:

我在将 ER 模型映射到关系模型时遇到问题。我试图简化我的情况。 假设有 3 个实体 A、B 和 C,以及 2 个关系 R1 和 R2

[A] ---(1,n) <<R1>>(1,1) === [[B]] === (1,n)<<R2>> (1,1) ==== [[C]]

A有key、ak等属性。 B 是弱的,由 ak 和 bk 标识(这是一个 wek/partial key) 到目前为止..映射一切正常,我将有 2 个关系

  • A(ak, a1, ...., an) ak 作为主键
  • B(bk, ak, b1, ..., bn) 以 (bk, ak) 作为主键,ak 外键引用 A(ak)

C 有什么用? 我认为 C 有 ck 喜欢偏键,但是如何映射新关系?

C (ck, bk, ak, c1, ..., cn) 与

  • (ck, bk, ak) 作为主键,bk 作为外键引用 B(bk),ak 引用 B(ak)?
  • (ck, bk, ak) 作为键,bk 作为外键引用 B(bk),ak 引用 A(ak)?

或其他类似的东西,例如:

  • C (ck, bk, c1, ..., cn) 以 (ck, bk) 作为键,bk 作为外键引用 B(bk)?

考虑最终的 SQL 并没有多大帮助,因为我认为不允许使用多个外键(例如 FOREIGN KEY (bk,ak) REFERENCES B(bk, ak)

我搜索了很多书,但没有找到类似的情况。这个时候我真的很迷茫... 我希望你能帮助我:-) 提前致谢

【问题讨论】:

  • 您有 ERD 的图像吗?
  • 您不希望拥有多个组合主键,这将导致它们在引用表中的副本。您应该引入代理单字段 id 主键并引用它们,并可能将这些字段组合成一个唯一索引。阅读更多关于 db 规范化和范式的信息。希望对您有所帮助。
  • @SergeyBenner:代理与自然键是一个非常激烈的讨论。双方各有利弊,取决于许多变量。
  • 感谢 Sergey 和 ypercube。您的回答向我证实了对这个论点有更多的思考方式,可能暗示着一个tred-off的解决方案。
  • @SergeyBenner:我设计的表在 2 年内添加了 110 亿行(每分钟 300 万行),具有 15 列自然键。替代与自然的使用在此处离题:在dba.stackexchange.com/questions 上提问以进行更全面的讨论

标签: sql database foreign-keys entity-relationship


【解决方案1】:

BPRIMARY KEY(bk, ak),所以这是您应该从C 引用的1:n 关系:

(ck, bk, ak) as PRIMARY KEY,
(bk, ak) as FOREIGN KEY referencing B(bk, ak)

这在 SQL 中是允许的:

CREATE TABLE C
( ck, bk, ak, ...
, PRIMARY KEY (ck, bk, ak)
, FOREIGN KEY (bk, ak) 
    REFERENCES B (bk, ak)
) 

【讨论】:

  • 非常感谢你的回答,现在我可以安静点了。但在实际工作中,在表 C 中有一个复合主键,这是一个好习惯吗?我认为最好有一个新的主键,并且将(ak,bk)作为外键......它是否正确?
  • 双方各有利弊。看到很多相关问题:Surrogate vs. natural/business keys
  • 我尽可能喜欢自然键。但好的做法是使用窄主键。因此,如果这些ak, bk, ckVARCHAR(200),它们显然不适合制作主键(或主键的一部分)。如果它们是简单整数或CHAR(5),它们不会是性能问题。
  • 在像您这样的情况下,复合键的一个优点是您可以在某些查询中使用较少的连接。假设您只想显示表AC 中的数据(而不是B),并且您在B 中有一个新的代理主数据库。您必须使用 A JOIN B ON B.ak = A.ak JOIN C ON C.New_B_pk = B.New_B_pk 连接所有 3 个表,这比使用原始设计的效率要低得多:A JOIN C ON C.ak = A.ak(少一个连接操作,并且不查找表 B 的索引。 )
猜你喜欢
  • 1970-01-01
  • 2018-08-25
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
  • 2018-12-12
  • 2017-05-26
相关资源
最近更新 更多