繁体   English   中英

引用具有多个外键的两列主键

[英]Referencing a two column primary key with multiple foreign keys

在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)
);

为什么这个陈述不起作用? 或者更具体地说,为什么它不起作用? 我试图创建这种类型的关系的原因是,在将来,我想要删除BD ,但保持关系FK_E

我收到错误:

ORA-02270:此列列表没有匹配的唯一键或主键

“为什么这个陈述不起作用?或者更具体地说,为什么它不起作用?”

您已将A上的主键定义为两列(A,B)的复合。 引用PK_AB的任何外键必须与这些列匹配。 这是因为一个外键必须拥有在子表中任何给定行所引用的表标识一行 复合主键意味着列AA可以包含重复值,因此列AB可以包含重复值; 只有(A,B)的排列是唯一的。 因此,引用外键需要两列。

Create Table B
( D int, E int, F int,
  Constraint fk_de Foreign Key (D,E) References A(A,B)
);

“由于表B引用了多个PK,”

错误。 B引用一个主键,恰好包含多个列,

“说,在将来,我想删除BD,但保持关系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)上有一个列约束。 但是,我认为引用唯一约束而不是主键是不好的做法,即使它是允许的。 我认为这部分是因为独特的约束通常强制执行业务密钥,因此意味着变更的可能性,但主要是因为引用主键只是行业标准。

在创建表B之前,尝试为列AB创建两个单独的索引

CREATE INDEX a_idx ON A (A);
CREATE INDEX b_idx ON A (B);

但可能你需要在表B上使用复合FK

Create Table B
( D int, E int, F int,
  Constraint fk_d Foreign Key (D,E) References A(A,B)
);

外键始终引用另一个表的PK。 A和B都不是PK的......你有多个PK。

Constraint fk_d Foreign Key (D,E) References A(A,B)

此外,数据库无法验证部分空的多个外键,因此我认为还需要将检查约束添加到表中。

alter table B add constraint check_nullness
    check ( ( D is not null and E is not null ) or
                ( D is null and E is null ) )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM