与复合主键约束的多对多关系

时间:2015-06-04 13:37:20

标签: mysql foreign-keys many-to-many

我要求DBMS中的多对多关系设计与其他约束。

有两个表t1t2,其中t1.idt2.id分别是主键。 t1t2具有多对多关系,因此自然设计是添加带有外键的第三个表t3。例如,

t3:
id
t1_id     (foreign key refereed to t1.id)
t2_id     (foreign key refereed to t2.id)

另一项要求 pair(t1.id, t2.id)应与t4.id具有一对一关系。用t5添加primary_key(t1.id, t2.id)是否合适?或者我们可以直接使用t3's t1_id, t2_id作为复合主键?我们需要快速扫描pair(t1.id, t2.id) t4中是否有实体,即pair(t1.id, t2.id)t4.id具有一对一的关系。

感谢您是否可以给我一些提示。

1 个答案:

答案 0 :(得分:0)

如果您必须在(t1.id,t2.id)t4.id之间强制实施一对一的关系,那么这似乎表明(t1.id,t2.id)将是唯一的。

如果是这种情况,如果(t1.id,t2.id) t3 中应该是唯一的,那么你可以将PRIMARY KEY作为 t3

您可以添加对 t4 的外键引用,并使其成为UNIQUE,因此 t3 中的一行只能与 t4 。或者,您可以将外键引用转到另一个方向,并将 t3 的主键值存储在 t4 中。

例如,要将 t3 中的外键设为 t4

 CREATE TABLE t3
 ( t1_id  INT NOT NULL       COMMENT 'pk, fk ref t1'
 , t2_id  INT NOT NULL       COMMENT 'pk, fk ref t2'
 , t4_id  INT                COMMENT 'fk ref t4'
 , PRIMARY KEY (t1_id,t2_id)
 , CONSTRAINT t3_ux2 UNIQUE KEY (t4_id)
 , CONSTRAINT fk_t3_t1 FOREIGN KEY (t1_id) REFERENCES t1(id)
     ON DELETE CASCADE ON UPDATE CASCADE
 , CONSTRAINT fk_t3_t2 FOREIGN KEY (t2_id) REFERENCES t2(id)
     ON DELETE CASCADE ON UPDATE CASCADE
 , CONSTRAINT fk_t3_t4 FOREIGN KEY (t4_id) REFERENCES t4(id)
     ON DELETE RESTRICT ON UPDATE CASCADE
 ) ...

或者,您可以在 t3 上引入代理主键。 (如果有其他表具有对 t3 的外键引用,我们通常只会执行此操作;因为现在 t3 的行为更像是实际实体,而不是纯粹的关系。这避免了我们不得不在另一个表中使用复合键作为外键来引用 t3

例如:

 CREATE TABLE t3
 ( id     INT NOT NULL       COMMENT 'pk'
 , t1_id  INT NOT NULL       COMMENT 'fk ref t1'
 , t2_id  INT NOT NULL       COMMENT 'fk ref t2'
 , PRIMARY KEY (t3_id)
 , CONSTRAINT t3_ux1 UNIQUE KEY (t1_id,t2_id)
 , CONSTRAINT fk_t3_t1 FOREIGN KEY (t1_id) REFERENCES t1(id) 
     ON DELETE CASCADE ON UPDATE CASCADE
 , CONSTRAINT fk_t3_t2 FOREIGN KEY (t2_id) REFERENCES t2(id) 
     ON DELETE CASCADE ON UPDATE CASCADE
 ) ...

您可以在此表 t3 中添加一个外键,以引用 t4 ,如上例所示。

或者你可以实现从 t4 到引用 t3 的关系。

无论哪种方式都有效。

我的决定主要基于

1)避免将复合键作为外键(如果没有实体表具有复合键)

2)我们是否需要ON DELETE CASCADE功能,以及需要采用哪种方式...从 t3 删除应该删除 t4 ,或者相反。

我在示例中展示ON DELETE RESTRICT我将t4_id fk列添加到 t3 。我认为从 t4 删除可能不会通过从 t3中删除行来“破坏” t1 t2 之间的关系