SQL Server三重多对多关系

时间:2019-04-11 09:34:27

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

我正在尝试为员工培训网站建立一个数据库。

它的工作方式如下:

  1. 将为每个员工分配一个或多个模块。

  2. 每个模块都将被分配课程,一次或多次。

同一模块可以分配给多个员工,而同一课程可以分配给多个模块。

每门课程的状态均为已完成,并且根据该员工为该模块完成所有课程的时间,每个模块的状态也将为完成。

那么这会是三级关系吗?还是三对多关系? 数据库将如何设置?

到目前为止,这是我在想什么。

员工

 EmployeeID 
 Name

模块

 ModuleID
 ModuleName
 Status

课程

 CourseID
 CourseName
 Status

EmployeesModules

 EmployeeID
 ModuleID

模块课程

 ModuleID
 CourseID

我认为这是不对的,因为课程不是每个员工都独有,但每个模块都不是目的。

如何改进此设计?

1 个答案:

答案 0 :(得分:1)

考虑以下ERD:

ERD

首先对图表进行一些说明...

在此ERD中,蓝色实体类型类似于主表。绿色实体类型类似于交易表。对于属性,带下划线的是候选键。您可能是一个喜欢每个表的代理键的人-如果是这样-快到前面,或者您可以使用图中所示的(有时是复合键)。只要图中的键是唯一的,就可以了。

现在,我在说什么,它对您有什么帮助?...

您担心的是,您希望根据分配给他们的每个课程跟踪每个员工的进度,并且,如果我理解正确,您还希望针对每个员工的整个模块跟踪状态。

要执行此操作,您需要将课程和模块(蓝色实体类型)的定义与跟踪谁接受它们(绿色实体类型)分开。因此,您在问题中提出的表格还不足以满足您的需求。特别是,您不能拥有Course.status字段,因为状态显然会因参加课程的人而异。

您的情况并非真正需要三对多。相反,我建议的是,为每个分配给某个模块的员工,都为该特定员工和模块创建一组注册记录。请注意,这使得模块(注册)和课程(注册)之间是一对多的,而不是多对多的,因为一旦员工注册了该模块,该模块的子课程便是已知的。如果您关注我,那么就这名员工而言,其他模块中发生的事情以及模块之间如何共享课程都无关紧要。

现在,您可以在Employee_Course_Status表中针对每个课程跟踪员工的进度。您必须在代码中管理的唯一潜在问题是Module_Enrolment.EmployeeModuleStatus的值。根据您的业务规则,这可能是根据课程级别的许多状态值来计算的。这样会产生一点冗余,并有可能出现更新异常(其中您的课程状态值和模块状态值不再正常)。

这是您必须管理的风险。您的架构可以使用数据库规范化和声明性引用约束来防止多种类型的数据不一致,但是有时您只需要诉诸于基于代码的控件即可。