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

Database constraints based on relationship dependencies

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

的特定实例的外键

例如,假设我们有以下 tables:

考虑到我要施加的约束,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] 没有关系

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

我认为前三个 table 和你的一样。 (但要使用更短的名称。如果您打算在问题中使用无意义的名称,至少让它们更短。)

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)
);

table "t3" 有点不同。 unique 约束看起来是多余的,其实不然。它让这对列成为外键引用的目标。

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

最后一个 table、"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"

这似乎是正确的。