Mysql 数据库设计-多个外键

Mysql 数据库设计-多个外键,mysql,sql,database,orm,Mysql,Sql,Database,Orm,我的数据库包含学校、部门和课程。学校可以有分部,也可以没有分部,课程与学校相关,也可以有分部,也可以没有分部(学校可以没有分部,或者课程可以跨分部) 我的表格当前设置如下: 学校: ID | name -------------------- harvard | Harvard University mit | MIT ucla | UCLA 部门(id+学校=唯一) 课程: ID | school (FK) | division | name --------

我的数据库包含学校、部门和课程。学校可以有分部,也可以没有分部,课程与学校相关,也可以有分部,也可以没有分部(学校可以没有分部,或者课程可以跨分部)

我的表格当前设置如下:

学校

ID       | name
--------------------
harvard  | Harvard University
mit      | MIT
ucla     | UCLA
部门
(id+学校=唯一)

课程

ID | school (FK) | division | name
-------------------------------------------------
1  | harvard     | eng      | Intro to Engineering 
2  | harvard     | arc      | Intro to Architecture
3  | harvard     |          | Statistics
4  | mit         |          | Math
我对此表示关注:

  • 没有验证来确保
    课程
    中的分区存在并且与学校相关
  • 分裂实际上不是一个fk
  • 需要两个查询才能得到学校和部门
有更好的方法吗?我希望能够:

  • 查询所有“哈佛”课程
  • 查询所有“哈佛工程”课程
  • 查询所有“哈佛工程和哈佛通识”课程

您可以创建多列外键:

CREATE TABLE course (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    school VARCHAR(50),
    division VARCHAR(50),
    name VARCHAR(50),
    FOREIGN KEY (school, division) REFERENCES division(school, id)
);
但是,最好在
分区
表中使用单独的
自动增量
列,并将其用作外键。这样,您就不必在
课程
表中重复两列

CREATE TABLE division (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    division_code VARCHAR(50),
    school VARCHAR(50),
    name VARCHAR(50),
    UNIQUE KEY (division_code, school),
    FOREIGN KEY (school) REFERENCES school (id)
);
CREATE TABLE course (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    division_id INT(11),
    name VARCHAR(50),
    FOREIGN KEY (division_id) REFERENCES division(id)
);

如果总是可以创建复合外键。但是,我建议对您的设计进行以下更改:

  • 为每个学校创建一个名为“General”的默认分区
  • 允许同一门课程存在于不同学校的可能性(在现实生活中,这可能会发生)
此外,我建议对所有表使用自动递增的整数主键,而不是依赖手工生成的名称

考虑以下设计,遵循上述原则:

school
    id            primary key
    name

division
    id            primary key
    school_id     foreign key to school(id)
    name

course
    id            primary key
    name

course_division
    id            primary key
    course_id     foreign key to course(id)
    division_id   foreign key to course(id)

下面是使用此模式的查询

查询所有“哈佛”课程

查询所有“哈佛工程”课程

查询所有“哈佛工程和哈佛通识”课程

school
    id            primary key
    name

division
    id            primary key
    school_id     foreign key to school(id)
    name

course
    id            primary key
    name

course_division
    id            primary key
    course_id     foreign key to course(id)
    division_id   foreign key to course(id)
SELECT c.* 
FROM course c
INNER JOIN division d ON d.id = cd.division_id
INNER JOIN school s ON s.id = d.school_id AND s.name = 'Harvard University'
SELECT c.* 
FROM course c
INNER JOIN course_division cd ON cd.id = c.course_id 
INNER JOIN division d ON d.id = cd.division_id AND d.name = 'School of Engineering'
INNER JOIN school s ON s.id = d.school_id AND s.name = 'Harvard University'
SELECT c.* 
FROM course c
INNER JOIN course_division cd ON cd.id = c.course_id 
INNER JOIN division d ON d.id = cd.division_id AND d.name IN ('School of Engineering', 'General')
INNER JOIN school s ON s.id = d.school_id AND s.name = 'Harvard University'