在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:此列列表没有匹配的唯一键或主键
3 回答
您已将A上的主键定义为两列(A,B)的复合 . 引用PK_AB的任何外键必须与这些列匹配 . 这是因为外键必须标识引用表中的一行,该行拥有子表中的任何给定行 . 复合主键表示列A.A可以包含重复值,因此列A.B;只有(A,B)的排列是唯一的 . 因此,引用外键需要两列 .
错误 . B引用一个主键,恰好包含多个列,
这没有意义 . 可以这样想:D不是B的属性,它是属性B通过它对表A的依赖继承 .
避免这种情况的一种方法是使用代理(或合成)密钥 . 复合键通常是业务键,因此它们的列在业务上下文中是有意义的 . 有意义的列值的一个特征是它们可以更改,并且将这些更改级联到外键可能会很混乱 .
实现代理键如下所示:
当然,你可以使用你发布的模式来做这件事,因为你已经在A(C)上有一个列约束 . 但是,我认为引用唯一约束而不是主键是不好的做法,即使它是允许的 . 我认为这部分是因为独特的约束通常强制执行业务密钥,因此意味着变更的可能性,但主要是因为引用主键只是行业标准 .
在创建表
B
之前,尝试为列的A
和B
创建两个单独的索引但是你可能需要在 table 上使用复合FK
B
此外,数据库无法验证部分空的多个外键,因此我认为还需要将检查约束添加到表中 .