我试图在数据库模式中模拟一个棘手的案例,以避免可能的不一致。下图大致描述了当前的情况,有3个表互相交互,table1和表2有N:M关系,table2和table3有另一个N:M关系,table1和table3有1:N的关系。我需要以某种方式添加一个约束,这样当table2和table1(table3的特定实例的外键)之间也存在关系时,table2和table3之间只能存在关系。
举个例子,我们假设我们有以下表格:
考虑到我想要施加的约束,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]无关。
答案 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"
这似乎是正确的。