在典型的RDB中,我可以描述与外键的关系。然而,我不知道如何能够有效地描述一个群体内部的关系。我知道这很难理解,所以让我来描述一下这个场景。
我想做一个梯度书服务,在那里教师可以注册和创建课程,学生可以注册和注册课程。
CREATE TABLE teachers (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255),
...
)
CREATE TABLE students (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255),
...
)
CREATE TABLE classes (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255),
teacher_id BIGINT REFERENCES teachers(id)
)
CREATE TABLE enrollments (
student_id BIGINT REFERENCES students(id),
class_id BIGINT REFERENCES classes(id),
PRIMARY KEY (student_id, class_id)
)在每堂课上,老师都可以做作业,每个学生都会得到作业的分数。
CREATE TABLE assignments (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255),
class_id BIGINT REFERENCES class(id)
...
)现在,我要描述一个分数属于一个学生,和一个外键作业。
CREATE TABLE scores (
id BIGSERIAL PRIMARY KEY,
score INT,
student_id BIGINT REFERENCES student(id),
assignment_id BIGINT REFERENCES assignments(id)
)然而,没有什么能阻止我为一个没有参加这门课的学生创造一个分数。换句话说,分数必须附有相应的注册(相同的学生身份)。我之所以说这是子关系,是因为分数的关系应该在一个类中局部地限定范围。
我如何在RDB中强制执行这样的限制?
更新
根据@Joel的建议,这就是我想出的。
CREATE TABLE enrollments (
class_id BIGINT REFERENCES classes(id),
student_id BIGINT REFERENCES students(id),
PRIMARY KEY (class_id, student_id)
);
CREATE TABLE assignments (
id BIGSERIAL,
class_id BIGINT REFERENCES classes(id),
name VARCHAR(255) NOT NULL,
max_possible_score INT NOT NULL,
PRIMARY KEY (id, class_id)
);
CREATE TABLE scores (
class_id BIGINT,
student_id BIGINT,
assignment_id BIGINT,
PRIMARY KEY (assignment_id, class_id, student_id),
FOREIGN KEY (class_id, student_id) REFERENCES enrollments(class_id, student_id),
FOREIGN KEY (assignment_id, class_id) REFERENCES assignments(id, class_id)
);发布于 2015-10-25 12:46:48
如果要确保学生在未注册的班级的作业中不能获得SCORE,则有两个选项:
有些人可能会说,您现在的数据模型工作得很好,但是它需要一些应用程序逻辑来对创建SCORE进行理智检查,以确保学生应该有这个分数。
如果要确保不使用应用程序逻辑就不会发生这种情况,则必须更改数据模型。当前的数据模型如下所示:

您可以将数据模型改为如下所示:

请注意以下事项:
Assignment部分是由CLASS的外键识别的。这将类ID向下拉到赋值,以便由SCORE在其主键中依次引用它。SCORE与ENROLLMENT直接相关,而不是与STUDENT直接相关。这是有意义的,因为注册是属于一个班级的学生的记录,所以它更紧密地模拟了你所关心的强加的商业规则。SCORE的主键由ENROLLMENT (包括学生ID)和ASSIGNMENT (包括类ID)的外键组成。SCORE的主要关键是课堂、作业和学生的结合。如果您确保在SCORE表中只保留了一个类ID副本,那么学生就不可能在作业中获得分数,除非该学生也注册了分配该作业的班级。
https://stackoverflow.com/questions/33328539
复制相似问题