在Oracle中获取以下两个表:
Create Table A
( A int, B int, C int,
Constraint pk_ab Primary Key(A, B),
Unique (C)
);
Create Table B
( D int, E int, F int,
Constraint fk_d Foreign Key (D) References A(A),
Constraint fk_e Foreign Key (E) References A(B)
);
为什么这个语句不起作用?或者更具体地说,为什么它不起作用?我尝试创建这种类型的关系的原因是,将来我想删除 B.D
,但保留关系 FK_E
。
我收到错误:
ORA-02270: no matching unique or primary key for this column-list
最佳答案
"Why doesn't this statement work? Or more specifically, why shouldn't it work? "
您已将 A 上的主键定义为两列 (A,B) 的组合。任何引用 PK_AB 的外键必须在数量上与这些列匹配。这是因为外键必须标识引用表中的单个行,该行拥有子表中的任何给定行。复合主键意味着 A.A 列可以包含重复值,A.B 列也可以包含重复值;只有 (A,B) 的排列是唯一的。因此,引用外键需要两列。
Create Table B
( D int, E int, F int,
Constraint fk_de Foreign Key (D,E) References A(A,B)
);
"Since there are multiple PK's that table B references"
错了。 B 引用单个主键,该主键恰好包含多个列,
" say, in the future, I want to delete B.D, but keep the relation fk_e. "
这没有道理。可以这样想:D 不是 B 的属性,而是 B 通过依赖表 A 继承的属性。
避免这种情况的一种方法是使用代理(或合成)键。复合键通常是业务键,因此它们的列在业务上下文中有意义。有意义的列值的一个特征是它们可以更改,并且将此类更改级联到外键可能会很困惑。
实现代理键如下所示:
Create Table A
( id int not null, A int, B int, C int,
Constraint pk_a Primary Key(ID),
constraint uk_ab Unique (A,B)
);
Create Table B
( a_id int, F int,
Constraint fk_n_a Foreign Key (A_ID) References A(ID)
);
当然,您可以使用您发布的架构来执行此操作,因为您已经对 A(C) 有单列约束。但是,我认为引用唯一约束而不是主键是不好的做法,即使这是允许的。我认为这部分是因为独特的约束通常强制执行业务键,因此意味着改变的潜力,但主要是因为引用主键只是行业标准。
关于sql - 使用多个外键引用两列主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14543846/