加入自我时防止多对多连接表的典型方法

时间:2017-05-15 14:34:08

标签: mysql sql database database-design many-to-many

我正在为数据库项目建立一所学校,我有很多关系,加入一个course表来建立先决条件。表格(简化)如下所示:

CREATE TABLE course_prereqs (
  course_id INT NOT NULL,
  prereq_id INT NOT NULL,

  PRIMARY KEY (course_id, prereq_id),
  FOREIGN KEY (course_id) REFERENCES course (course_id),
  FOREIGN KEY (prereq_id) REFERENCES course (course_id)
)

我想知道的是最简单但也是最友好的方式,可以防止(1, 2), and (2, 1)成为表中的先决条件,因为它会导致周期性依赖。

我在考虑与

相当的东西
-- in a trigger though since MySQL doesn't have check
CHECK (course_id < prereq_id) 

虽然有效,但我觉得最终用户总是要确保course_id始终小于prereq_id可能会很烦人。

有更好的方法,还是我高估了必须确保course_id总是更小的不便?

2 个答案:

答案 0 :(得分:1)

这似乎是一个应用程序问题。当说&#34;当然#1是先决条件&#39;当然#2&#34;后来说'#34;当然#2是#1的先决条件是不正确的。&#34;。也就是说,为什么你需要数据库来检查一些永远不会发生的事情?

另一方面,如果&#39;关系&#39;反身(1-> 2意味着2-> 1),然后我会这样做:

INSERT IGNORE (a, b) VALUES (LEAST($this, $that), GREATEST($this, $that));

所以有一个规范的&#39;存储关系的顺序。测试变得更加混乱。

或......存储两种关系。它只是行数的两倍,但查找性能不会明显受到影响。

在这两种情况下,您都需要两个索引:

PRIMARY KEY(a, b),
INDEX      (b, a)

答案 1 :(得分:0)

在插入新课程之前,请检查cnt = 0

select count(1) cnt from course_prereqs where course_id = new_prereq_id and prereq_id = new_course_id