由于以下几个原因,循环引用可能不好:
- 在关系必须存在的情况下(即,教师必须有班级,班级必须有教师,两者从业务和技术需求的角度来看),您会遇到先有鸡还是先有蛋的场景:您无法添加没有课程的老师,也无法添加没有老师的课程。
- 很难弄清楚层次结构的“顶部”是什么(因为说实话,没有“顶部”)
假设您可以有没有课程的老师和/或没有课程的科目,听起来这两者中的一个将是“顶级”(从商业角度来看,我假设它会是科目)。
如果您所拥有的一切正常,我认为设计没有问题,也没有其他设计方法。
评论后编辑
单向依赖没有问题(这就是普通的不可为空的外键)。
根据您的评论,我觉得我也应该指出一些事情:对循环依赖的反对意见是技术上的,而不是逻辑上的。如果企业说没有课就没有老师,没有老师就没有课,那很好;您只是无法以这种方式对数据进行建模,否则您将永远无法添加任何内容。您必须定义哪些对象(班级或教师)可以独立存在(从技术角度,而不是业务角度)。
您在教师和班级之间存在 M:M 关系这一事实在一定程度上拯救了您,因为这迫使您使 两者 能够孤立地存在(因为这种联系是在链接表,而不是参与者表本身。
因此,您没有真正的循环依赖。您的业务逻辑是循环的,但这很好,因为您可以完全控制它的运行方式。您的布局如下所示:
Teacher <----- TeacherClass -----> Class
^ ^
| |
| |
TeacherSubject --------------------> Subject
(如果一个老师可以有多个科目)
或者这个:
Teacher <----- TeacherClass -----> Class
| ^
| |
| |
\----------------------------> Subject
(如果一个老师只能有一个科目)
或者这个:
Teacher <----- TeacherClass -----> Class
^ ^
| |
| |
\----------------------------- Subject
(如果一个科目只能有一位老师)
在第一种情况下,Teacher 和Class 都是顶级实体,因为它们都不指向其他任何东西(链接表完成了这一点)。第二种,只有Class是顶级实体。
只要路径上的某处存在顶级实体,就可以了。首先,您可以按以下顺序添加记录:
Teacher -> Class -> (TeacherClass -> Subject) -> TeacherSubject
(我将TeacherClass -> Subject 括在括号中,因为您可以按任何顺序添加它们)
第二个,可以按这个顺序添加:
Class -> Subject -> Teacher -> TeacherClass
第三个,可以按这个顺序添加:
Class -> Teacher -> (TeacherClass -> Subject)
因此,从技术角度来看,您没有真正的循环依赖。