问题描述
嗨,汤姆
我有一张有两列的表。如果列1中的值='A',则列2中的值必须引用
表1 :
到期1到期2
1个锯子
2密耳
表2 :
在1在2
35元素
45法
表3 :
到时1到时2
S2
P35
我希望在表3中使用外键约束,
在表3中,如果列“atdue1”的值=“S”,则列atdue2必须具有一个外键,该外键指向表1的列“到期1”的引用
在表3中,如果列“atdue1”的值=“P”,则列atdue2必须具有一个外键,该外键指向表2的列“at1”的引用。
这可能吗?请协助。
我有一张有两列的表。如果列1中的值='A',则列2中的值必须引用
表1 :
到期1到期2
1个锯子
2密耳
表2 :
在1在2
35元素
45法
表3 :
到时1到时2
S2
P35
我希望在表3中使用外键约束,
在表3中,如果列“atdue1”的值=“S”,则列atdue2必须具有一个外键,该外键指向表1的列“到期1”的引用
在表3中,如果列“atdue1”的值=“P”,则列atdue2必须具有一个外键,该外键指向表2的列“at1”的引用。
这可能吗?请协助。
专家解答
不,你不能有这样的条件外键。
有几种方法可以解决这个问题:
1.为T3上的T1和T2创建指向相关表的可选列。确保只设置了一个
2.为T1和T2创建主表2.将T3的FK指向主表
3.创建M:M表,反转关系
那它们是怎么工作的呢?让我们看看:
1.可选列
这样做的工作方式如下:
2.主表
3、M:M表
我个人更喜欢主表方法(2)。不过,你需要自己权衡不同方法的实用性。
如果您想了解更多信息,请查看此演示文稿(幻灯片32 ) :
http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back
或者
http://stackoverflow.com/a/922341/1485955
有几种方法可以解决这个问题:
1.为T3上的T1和T2创建指向相关表的可选列。确保只设置了一个
2.为T1和T2创建主表2.将T3的FK指向主表
3.创建M:M表,反转关系
那它们是怎么工作的呢?让我们看看:
1.可选列
这样做的工作方式如下:
CREATE TABLE t1 (due1 int primary key, due2 varchar2(3));
INSERT INTO t1 VALUES (1, 'saw');
INSERT INTO t1 VALUES (2, 'mil');
CREATE TABLE t2 (at1 int primary key, at2 varchar2(7));
INSERT INTO t2 VALUES (35, 'element');
INSERT INTO t2 VALUES (45, 'method');
create table t3 (
tp varchar2(1),
t1_id int references t1 (due1),
t2_id int references t2 (at1),
constraint one_fk check (
( tp = 'S' and t1_id is not null and t2_id is null ) or
( tp = 'P' and t1_id is null and t2_id is not null )
)
);
insert into t3 values ('S', null, 35);
SQL Error: ORA-02290: check constraint (CHRIS.ONE_FK) violated
insert into t3 values ('P', null, 35);
insert into t3 values ('S', 2, 35);
SQL Error: ORA-02290: check constraint (CHRIS.ONE_FK) violated
insert into t3 values ('P', 2, null);
SQL Error: ORA-02290: check constraint (CHRIS.ONE_FK) violated
2.主表
drop table t3 purge;
drop table t1 purge;
drop table t2 purge;
drop table tmaster purge;
create table tmaster (
id int primary key,
tp varchar2(1) not null,
unique (id, tp)
);
INSERT INTO tmaster VALUES (1, 'S');
INSERT INTO tmaster VALUES (2, 'S');
INSERT INTO tmaster VALUES (35, 'P');
INSERT INTO tmaster VALUES (45, 'P');
CREATE TABLE t1 (
due1 int primary key, due2 varchar2(3),
tp varchar2(1) not null check (tp = 'S'),
foreign key (due1, tp) references tmaster (id, tp)
);
INSERT INTO t1 VALUES (1, 'saw', 'S');
INSERT INTO t1 VALUES (2, 'mil', 'S');
CREATE TABLE t2 (at1 int primary key, at2 varchar2(7),
tp varchar2(1) not null check (tp = 'P'),
foreign key (at1, tp) references tmaster (id, tp)
);
INSERT INTO t2 VALUES (35, 'element', 'P');
INSERT INTO t2 VALUES (45, 'method', 'P');
create table t3 (
tmaster_id int references tmaster (id)
);
insert into t3 values (1);
insert into t3 values (35);
3、M:M表
drop table tmaster purge;
drop table t3 purge;
drop table t1 purge;
drop table t2 purge;
CREATE TABLE t1 (due1 int primary key, due2 varchar2(3));
INSERT INTO t1 VALUES (1, 'saw');
INSERT INTO t1 VALUES (2, 'mil');
CREATE TABLE t2 (at1 int primary key, at2 varchar2(7));
INSERT INTO t2 VALUES (35, 'element');
INSERT INTO t2 VALUES (45, 'method');
create table t3 (
id int primary key,
tp varchar2(1) not null,
unique (id, tp)
);
insert into t3 values (1, 'S');
insert into t3 values (2, 'P');
create table t1t3 (
t1_id int references t1 (due1),
t3_id int primary key,
tp varchar2(1) check (tp = 'S'),
foreign key (t3_id, tp) references t3 (id, tp)
);
create table t2t3 (
t2_id int references t2 (at1),
t3_id int primary key references t3 (id),
tp varchar2(1) check (tp = 'P'),
foreign key (t3_id, tp) references t3 (id, tp)
);
insert into t1t3 values (35, 1, 'S');
SQL Error: ORA-02291: integrity constraint (CHRIS.SYS_C005387) violated - parent key not found
insert into t1t3 values (1, 1, 'S');
insert into t2t3 values (35, 2, 'P');
insert into t2t3 values (1, 2, 'P');
SQL Error: ORA-00001: unique constraint (CHRIS.SYS_C005390) violated
我个人更喜欢主表方法(2)。不过,你需要自己权衡不同方法的实用性。
如果您想了解更多信息,请查看此演示文稿(幻灯片32 ) :
http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back
或者
http://stackoverflow.com/a/922341/1485955
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




