一个具有多列的外键VS多个具有单列的外键

时间:2017-08-31 11:38:57

标签: sql oracle

考虑以下两个SQL代码片段:

SQL代码1:

 CONSTRAINT FK_E
      FOREIGN KEY (E1, E2, E3)
      REFERENCES F (E1, E2, E3),

SQL代码2:

 CONSTRAINT FK_E1
      FOREIGN KEY (E1)
      REFERENCES F (E1),

 CONSTRAINT FK_E2
      FOREIGN KEY (E2)
      REFERENCES F (E2),

 CONSTRAINT FK_E3
      FOREIGN KEY (E3)
      REFERENCES F (E3),

我的问题:SQL代码1和SQL代码2是否相等?即它们是否以相同的方式在DBMS中解释?如果没有,它们之间有什么区别?

EDIT1:更具体地考虑以下ER图

enter image description here

以下SQL代码是否正确?

 CREATE TABLE E
 (EID NUMBER PRIMARY KEY);


 CREATE TABLE F
 (FID NUMBER PRIMARY KEY);


 CREATE TABLE G
      (EID NUMBER,
      FID NUMBER,
      GNAME VARCHAR(50),
      CONSTRAINT G_PK
           PRIMARY KEY (EID, FID, GNAME),
      CONSTRAINT FK_G_EID
           FOREIGN KEY (EID)
           REFERENCES E (EID),
      CONSTRAINT FK_G_FID
           FOREIGN KEY (FID)
           REFERENCES F (FID)
 );


 CREATE TABLE R1
      (EIDE NUMBER,
      EIDG NUMBER,
      FIDG NUMBER,
      GNAME VARCHAR(50),
      ATTR1 NUMBER,
      CONSTRAINT PK_R1
           PRIMARY KEY (EIDG, FIDG, GNAME),
      CONSTRAINT FK_R1_EIDG_FIDG_GNAME
           FOREIGN KEY (EIDG, FIDG, GNAME)
           REFERENCES G (EID, FID, GNAME),
      CONSTRAINT FK_R1_EIDE
           FOREIGN KEY (EIDE)
           REFERENCES E (EID)
 );


 CREATE TABLE R2
      (FIDF NUMBER UNIQUE,
      FIDG NUMBER,
      EIDG NUMBER,
      GNAME VARCHAR(50),
      ATTR2 NUMBER,
      CONSTRAINT PK_R2
           PRIMARY KEY (EIDG, FIDG, GNAME),
      CONSTRAINT FK_R2_EIDG_FIDG_GNAME
           FOREIGN KEY (EIDG, FIDG, GNAME)
           REFERENCES G (EID, FID, GNAME),
      CONSTRAINT FK_R2_FIDF
           FOREIGN KEY (FIDF)
           REFERENCES F (FID)
 );

EDIT2:FK_R1_EIDE和FK_R2_FIDF是多余的吗?

1 个答案:

答案 0 :(得分:1)

  

我的问题:SQL代码1和SQL代码2是否相等?

不,它们不相同。

截至the definition

  

外键约束

     

外键约束(也称为引用完整性   约束)将列指定为外键并建立一个   该外键与指定的主键或。之间的关系   唯一键,称为引用键。复合外键   将列的组合指定为外键。

根据上述声明:

CONSTRAINT FK_E
      FOREIGN KEY (E1, E2, E3)
      REFERENCES F (E1, E2, E3),

假设在F

上创建了主键或唯一约束
CREATE TABLE F(
  .....
  .....
  CONSTRAINT my_pk PRIMARY KEY(E1, E2, E3)
)

虽然这个声明

 CONSTRAINT FK_E1
      FOREIGN KEY (E1)
      REFERENCES F (E1),

 CONSTRAINT FK_E2
      FOREIGN KEY (E2)
      REFERENCES F (E2),

 CONSTRAINT FK_E3
      FOREIGN KEY (E3)
      REFERENCES F (E3),

需要存在三个约束,主键或唯一索引/约束:

CREATE TABLE F(
  .....
  .....
  CONSTRAINT my_pk1 PRIMARY KEY(E1),
  CONSTRAINT my_uq2 UNIQUE(E2),
  CONSTRAINT my_uq3 UNIQUE(E3)
)

注意1-该表只能有一个主键,因此示例中只有一个约束可以是主键,其余2个(或全部3个)必须是唯一键。

注2 - 主键约束和唯一键约束之间存在轻微的语义差异。主键值必须是唯一的,不得包含空值,而唯一键值可以为NULL。

在第一种情况下,表F可以包含这些值

E1  E2  E3
 1   1   1
 1   1   2
 2   2   1

并且子表只能包含这些记录:

E1  E2  E3
 1   1   1
 1   1   2
 2   2   1

但是你不能在子表中插入这些值的组合,因为它们在父表中不存在:

 E1  E2  E3
 1   2   1
 2   2   2

在第二种情况下,表F可以包含这些值

E1  E2  E3
 1   1   1
 2   2   2
 3   3   3

但不能包含这些值,因为每列必须是唯一的:

E1  E2  E3
 1   1   1
 1   1   2
 2   1   3

虽然子表可以包含这些记录:

E1  E2  E3
 1   2   3
 3   1   2
 2   1   3