0

我试图通过引用不同的表来设置外键。

想象一下这些表:

Active_Card((主键)Num_id号码, num_card号码,is_active varchar2);

TMP_CARD((PK)num_card number, reg_date date);

DEFINITIVE_CARD((PK num_card 号码,名称 varchar,create_date 日期)

所以 num_card 是 Active_Card 的外键。我的问题是如何在 Active_card 中引用两个表(TMP_CARD 和 DEFINITIVE_CARD)。

此致,

4

3 回答 3

2

让我们解释一下为什么这不是一个好主意,然后从那里开始:

第 1 假设 RDBMS 允许您执行此操作。

所以我们有Active_CardDefinitive_Card和相关的 FK Tmp_Card

现在假设我们有definitive_card123、456 的 #s 和 123、789 的tmp_card#s

外键强制参照完整性。所以 123 是可以的,因为它存在于两者中。456 和 789 不会,因为它在两个表中都不存在。

但这不是想要的。您指出它需要在任一表中,而不是在评论中指出:*为了在 Active_Card 中有一个条目,它必须在 DEFINITIVE_CARD 或 TMP_CARD 中存在一个条目*

因此,由于您不希望两者中的 card_number 相同,因此您实际上有 2-3 种选择:

  1. 将 Card_numbers 放在单独的表中,并通过关联表连接回 Active_card
  2. 在 Active_card 中放置第二个 card_number 列,并根据填充的字段告诉您要转到哪个表以获取更多信息。
  3. 将 Definitive_Card 和 tmp_card 中的所有字段放在同一个表中

这些选项中的每一个都有自己的优缺点列表:但是如果没有完全了解业务需求,我们无法说出哪个最适合您的情况。

我们可以说您的尝试在 RDBMS 中根本行不通;但以上 3 个选项中的任何一个都将满足能够添加适当外键的要求

于 2013-05-06T11:33:26.697 回答
2

我认为提议的设计要求是可疑的。我之前已经看到这种设计要求是由构建不良的对象模型进入构建不良的关系模型的。

尽管如此,如果要求是 active_card.num_card 必须引用两个表,则物化视图可以实现设计要求。

create table active_card( 
   num_id number primary key, 
   num_card number, 
   is_active varchar2(5) );
create table tmp_card( 
   num_card number primary key, 
   reg_date date );
create table definitive_card( 
   num_card number primary key, 
   name varchar(256), 
   create_date date );

create or replace view card_v as
select tc.num_card
  from tmp_card tc
 where exists ( select null 
                  from definitive_card dc 
                 where dc.num_card = tc.num_card );

alter table active_card 
   add constraint active_card_num_card_fk 
   foreign key (num_card) 
   references card_v (num_card); -- won't work

但是您不能针对视图创建外键...所以...创建一个物化视图:

create materialized view log on tmp_card;
create materialized view log on definitive_card;

create materialized view card_mv
   build immediate 
   refresh fast 
   on commit
   as 
   select tc.num_card
     from tmp_card tc
    where exists ( select null 
                     from definitive_card dc 
                    where dc.num_card = tc.num_card )
;

alter table active_card 
   add constraint active_card_num_card_fk 
   foreign key (num_card) 
   references card_mv (num_card); -- works

insert into tmp_card values ( 123, sysdate );
insert into tmp_card values ( 456, sysdate );
insert into tmp_card values ( 789, sysdate );
insert into definitive_card values ( 123, 'OneTwoThree', sysdate );
insert into definitive_card values ( 789, 'SevenEightNine', sysdate );
insert into definitive_card values ( 111, 'OneOneOne', sysdate );

commit;

现在...

insert into active_card values ( 1, 123, 'true' ); -- succeeds
insert into active_card values ( 1, 456, 'true' ); -- fails
insert into active_card values ( 1, 111, 'true' ); -- fails

delete from tmp_card where num_card = 789; -- succeeds
commit;

delete from tmp_card where num_card = 123; -- succeeds, but
commit; --fails

如果设计要求是 active_card.num_card 必须出现在两个表中的一个而不是两个表中,则需要调整物化视图定义。

于 2013-05-07T22:59:24.550 回答
0

我怀疑您不想同时引用两个表。您想参考其中一个

为此,请使用单独的独占 FK。或者,使用继承。更多信息在这里

于 2013-05-06T11:20:50.823 回答