Sql 如何将多个外键从ER模型映射到关系模型?

Sql 如何将多个外键从ER模型映射到关系模型?,sql,database,foreign-keys,entity-relationship,Sql,Database,Foreign Keys,Entity Relationship,我在将ER模型映射到关系模型时遇到了一个问题。我试图简化我的案件。 假设有3个实体A、B和C,以及2个关系R1和R2 [A] ---(1,n) <<R1>>(1,1) === [[B]] === (1,n)<<R2>> (1,1) ==== [[C]] [A]--(1,n)(1,1)=[[B]==(1,n)(1,1)==[[C]] A具有键、ak和其他属性。 B弱,由ak和bk识别(这是wek/部分密钥) 到现在为止映射都可以,我将有2个关系

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

[A] ---(1,n) <<R1>>(1,1) === [[B]] === (1,n)<<R2>> (1,1) ==== [[C]]
[A]--(1,n)(1,1)=[[B]==(1,n)(1,1)==[[C]]
A具有键、ak和其他属性。 B弱,由ak和bk识别(这是wek/部分密钥) 到现在为止映射都可以,我将有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并没有多大帮助,因为我认为不允许使用多个外键(例如,外键(bk,ak)引用B(bk,ak)

我找了很多书,但没有发现类似的情况。我现在真的很困惑。。。 我希望你能帮助我:-)
提前感谢表
B
主键是
(bk,ak)
,因此对于
1:n
关系,您应该从
C
中引用以下内容:

(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)
) 

B
主键是
(bk,ak)
,因此对于
1:n
关系,这是您应该从
C
中引用的:

(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)
) 


您有ERD的图像吗?您不希望有多个组合主键,这将导致它们在引用表中的副本。您应该引入代理单字段id主键并引用它们,并可能将这些字段合并到唯一索引中。阅读有关db规范化和范式的更多信息。希望能有帮助。@SergeyBenner:代理与自然关键是一个非常激烈的讨论。双方都有利弊,这取决于许多变量。谢谢你们,谢尔盖和伊佩尔切贝。您的回答向我证实了对这个论点有更多的思考方式,可能意味着一个tred-off解决方案。@SergeyBenner:我设计了一个表,它在2年内(每分钟300万行)添加了110亿行,具有15列的自然键。代理与自然的使用在这里是离题的:在上问一个问题进行更全面的讨论您是否有ERD的图像?您不希望有多个组合主键,这将导致它们在引用表中的副本。您应该引入代理单字段id主键并引用它们,并可能将这些字段合并到唯一索引中。阅读有关db规范化和范式的更多信息。希望能有帮助。@SergeyBenner:代理与自然关键是一个非常激烈的讨论。双方都有利弊,这取决于许多变量。谢谢你们,谢尔盖和伊佩尔切贝。您的回答向我证实了对这个论点有更多的思考方式,可能意味着一个tred-off解决方案。@SergeyBenner:我设计了一个表,它在2年内(每分钟300万行)添加了110亿行,具有15列的自然键。在这里,代孕与自然的使用是离题的:问一个问题进行更全面的讨论非常感谢你的回答,现在我可以更安静地继续了。但在实际工作中,在表C中有一个compund主键是一种好的做法吗?我认为最好是有一个新的主键一样长,而mantein(ak,bk)作为外键。。。这是正确的吗?双方都有利弊。看到很多相关的问题:我尽可能喜欢自然键。但好的做法是使用窄主键。因此,如果这些
ak,bk,ck
VARCHAR(200)
它们显然不适合制作主键(或主键的一部分)。如果它们是简单整数或
CHAR(5)
,则不会出现性能问题。在类似您的情况下,复合键的一个优点是,在某些查询中可以使用较少的连接。假设您只想显示表
A
C
中的数据(而不是
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
)非常感谢您的回答,现在我可以安静一点了。但在实际工作中,在表C中有一个compund主键是一种好的做法吗?我认为最好是有一个新的主键一样长,而mantein(ak,bk)作为外键。。。这是正确的吗?双方都有利弊。看到很多相关的问题:我尽可能喜欢自然键。但好的做法是使用窄主键。因此,如果这些
ak,bk,ck
VARCHAR(200)
它们显然不适合制作主键(或主键的一部分)。如果它们是简单整数或
CHAR(5)
,则不会出现性能问题。在类似您的情况下,复合键的一个优点是,在某些查询中可以使用较少的连接。假设您只想显示表
A
C
中的数据(而不是
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