我认为你最后的外键引用引用了错误的表。我在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"
这似乎是正确的。
在数据库设计中,您只需要添加一个完整性限制,指出“当table2和table1之间存在关系时,只能存在table2和table3之间的关系”。如果你想在sql中实现这个约束,你可以创建一个触发器。我也考虑过数据库设计中的其他选择,但我认为所有其他方案都会违反其他规则之一,或者有重复的数据(如果仅以一种关系表示table1_has_table2和table2_has_table3)。 – 2015-01-20 22:58:19