使用备用外键约束数据库

时间:2012-01-20 19:33:22

标签: sql oracle ddl

我有一个数据库表,我用它作为系统之间的接口。我写信给他们,他们从中读取。我在表中有一个引用我的用户表的外键。

现在界面变得越来越复杂。我现在有另一个用于接口表,不引用用户表。我当然可以放宽对用户表的外键约束。

我想要做的是有一个约束状态要么满足这个外键,要么满足另一个键(在不同的列中)。这可能吗?

我有一个oracle数据库。

3 个答案:

答案 0 :(得分:3)

您可以声明两列都可以为空,并创建一个检查约束,以确保两列中只有一列不为NULL。

例如,如果我有教授和讲师的单独表格,我想模拟课程,以便课程可以有教授或讲师,但不是两者,我可以做这样的事情

SQL> ed
Wrote file afiedt.buf

  1  create table professor(
  2    professor_id number primary key
  3* )
SQL> /

Table created.

SQL> create table lecturer(
  2    lecturer_id number primary key
  3  );

Table created.

SQL> create table class(
  2    class_id number primary key,
  3    lecturer_id number references lecturer( lecturer_id ),
  4    professor_id number references professor( professor_id ),
  5    check( (lecturer_id is null and professor_id is not null) or
  6           (lecturer_id is not null and professor_id is null) )
  7  );

Table created.

SQL> insert into professor values( 1 );

1 row created.

SQL> insert into lecturer values( 20 );

1 row created.

SQL> insert into class values( 1, 20, null );

1 row created.

SQL> insert into class values( 2, null, 1 );

1 row created.

SQL> insert into class values( 3, 20, 1 );
insert into class values( 3, 20, 1 )
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.SYS_C0014175) violated

当然,从数据建模的角度来看,创建一个INSTRUCTORINSTRUCTOR_TYPE通常更好,可以是LECTURERPROFESSOR并使用CLASS表的不可为空的外键创建INSTRUCTOR表。

答案 1 :(得分:0)

不,这是不可能的。你可以把那些连接到一个或另一个表的三级密钥表放在一起,但它非常凌乱而脆弱。

相反,我会高度建议您重新审视您的集成策略,因为您的当前版本似乎无法以您需要的方式进行弯曲。

答案 2 :(得分:0)

我会为新的界面要求创建一个不同的表。约束的一个区别只会导致另一个。

然后我会考虑是否应该创建一个视图,让应用程序软件从视图而不是从基表中读取。