我要求DBMS中的多对多关系设计与其他约束。
有两个表t1
和t2
,其中t1.id
和t2.id
分别是主键。 t1
和t2
具有多对多关系,因此自然设计是添加带有外键的第三个表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
具有一对一的关系。
感谢您是否可以给我一些提示。
答案 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 之间的关系