数据建模是艺术代表关系图中的真实世界。你的模式是正确的,但它是真的吗?
想一想,什么是CLASS?这是一个教师,一个主题和一个等级。那些是你的关系。此外,您还想强制规定主语适用于该等级,并且教师可以在该等级中教授该主语。
我认为你的问题在于使用交叉表中的代理键。这些表格代表您的多对多关系:teacher_subject
,grade_subject
。无论如何,这些都是合成表,而且它们只是由键组成。因此,复合主键就足够了。
代理主键没有意义,所以我们需要定义一个唯一约束grade_subject(subject_id, grade_id)
以确保我们没有两个记录('PHYSICS','YEAR 2')。鉴于grade_subject
是一个没有其他列添加代理键的交集表是毫无意义的。代理键的价值在于最小化业务密钥更改的影响。但grade_subject
没有商业密钥,只有两个代理键subject_id
和grade_id
。
当涉及到定义引用完整性时,这具有优势。
所以我会接近你的问题是这样的:
grade_subject
----------------
grade_id
subject_id
primary key (grade_id, subject_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
teacher_subject
---------------------
teacher_id
grade_id
subject_id
primary key (teacher_id,grade_id, subject_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
Class
-----------------------------------
id
teacher_id
grade_id
subject_id
primary key (id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
foreign key (teacher_id,grade_id,subject_id) reference teacher_subject (teacher_id,grade_id,subject_id)
这可能看起来像外键一堆了,我可以在审查阶段设想一些参数。 (我在grade_subject
上包含了外键,所以我有些事情可以承认我不关心那么多,所以可以承认)。
但我不喜欢通过像TEACHER_SUBJECT这样的辅助关系强制执行混淆CLASS_SUBJECT等重要数据关系。我不想加入到TEACHER_SUBJECT和SUBJECT_GRADE以便将CLASS加入到SUBJECT中。
现在,当后者间接强制执行前者时,为什么我会选择将参照完整性约束包含到单个父表和交叉表中?因为它使模型中的关系更清晰。我在该模型中强调,因为在物理数据库中,我可能会选择省略单个表外键或禁用它们,并相信交集表的关系完整性。
关于三列组合的一些问题使我感到困惑,我想是这样的:它没有足够标准化。你可能有一个特例,但更一般的模型是两个规则,TEACHER_SUBJECT和TEACHER_GRADE。这应该是这样的
teacher_subject
---------------------
teacher_id
subject_id
primary key (teacher_id, subject_id)
foreign key (subject_id) reference subject (subject_id)
foreign keye (teacher_id) reference teacher (teacher_id)
teacher_grade
---------------------
teacher_id
grade_id
primary key (teacher_id,grade_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (teacher_id) reference teacher (teacher_id)
Class
-----------------------------------
id
teacher_id
grade_id
subject_id
primary key (id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
foreign key (teacher_id,subject_id) reference teacher_subject (teacher_id,subject_id)
foreign key (teacher_id,grade_id) reference teacher_grade (teacher_id,grade_id)
当然,如果你还是想执行的规则德鲁先生只能教数学到第四剂和物理学到六年级学生就需要有TEACHER_SUBJECT_GRADE表。
您的数据模型没有解决的一件事是调度问题。学校的时间表必须网格化,所以课程需要适合预先确定的网格。您可能需要将时间表的插槽定义为单独的表格,并将CLASS链接到该表格。课堂也需要教室。那是另一张桌子。
非常感谢APC提供的答案和时间。你的设计中有两件事是我可怜的大脑无法理解的。 1)代理键:不会有一个唯一的(自动增量)整数是否足够?使用复合主键有什么好处? (2)在teacher_subject表中,为什么使用(grade_id,subject_id)作为外键,而grade_id和subject_id已被单独用作外键?对不起,我的无知。但如果你能向我解释这一点,我会很感激你。周末愉快。 – 2012-04-20 13:27:35