基于关系依赖性的数据库约束

时间:2015-01-20 20:55:19

标签: mysql database database-design relational-database

我试图在数据库模式中模拟一个棘手的案例,以避免可能的不一致。下图大致描述了当前的情况,有3个表互相交互,table1和表2有N:M关系,table2和table3有另一个N:M关系,table1和table3有1:N的关系。我需要以某种方式添加一个约束,这样当table2和table1(table3的特定实例的外键)之间也存在关系时,table2和table3之间只能存在关系。

enter image description here

举个例子,我们假设我们有以下表格:

enter image description here

考虑到我想要施加的约束,table3_has_table2中的第一行是有效的,因为table3 [0x000020]将table1 [0x0000A]作为FK而table2 [0x00010]在table1_has_table2中具有table1 [0x0000A]的条目,但是table3_has_table2中的第二行无效,因为table2 [0x00011]与table1_has_table2中的table1 [0x0000A]无关。

1 个答案:

答案 0 :(得分:2)

我认为您的上一个外键引用引用了错误的表。我在PostgreSQL中写了这个。对于MySQL,您只需要将内联约束移动到单独的约束子句中。

我认为前三张表与你的相同。 (但是名字较短。如果你在问题中使用毫无意义的名字,至少要把它们缩短。)

create table t1 (
  t1_id integer primary key
);

create table t2 (
  t2_id integer primary key
);

create table t1_has_t2 (
  t1_id integer not null references t1 (t1_id),
  t2_id integer not null references t2 (t2_id),
  primary key (t1_id, t2_id)
);

表" t3"有点不同。唯一约束看起来是多余的,但事实并非如此。它允许这对列成为外键引用的目标。

create table t3 (
  t3_id integer primary key,
  t1_id integer not null references t1 (t1_id),
  unique (t3_id, t1_id)
);

最后一个表格" t3_has_ts",与它需要一个不同类型的名称是不同的。它具有重叠的外键约束。

create table t3_has_ts (
  t3_id integer not null,
  t2_id integer not null,
  t1_id integer not null,
  foreign key (t1_id, t2_id) references t1_has_t2 (t1_id, t2_id),
  foreign key (t3_id, t1_id) references t3 (t3_id, t1_id),
  primary key (t3_id, t2_id, t1_id)
);

我使用整数列的整数。

insert into t1 values (10), (11);
insert into t2 values (16), (17);
insert into t3 values (32, 10);

insert into t1_has_t2 values (10, 16);
insert into t1_has_t2 values (11, 17);

-- This is the row you said should succeed.
insert into t3_has_ts values (32, 16, 10);

-- And this one should fail.
insert into t3_has_ts values (32, 17, 11); 

确实失败了。 PostgreSQL错误消息说

(32, 11) is not present in table "t3"

这似乎是正确的。