2

我在 ER 中发现了一个案例,在我的一生中,我无法弄清楚如何实现参照完整性。经典的 Employee、Manager、Department 关系可以说明这个问题。

具有以下约束:

  1. 员工只能在一个部门工作。
  2. 部门可以有很多员工。
  3. 员工可以有一名经理在同一部门工作。
  4. 经理可以有多个员工在同一个部门工作。
  5. 没有经理的员工就是经理。

这张图说明了这个概念。

员工、经理和部门 ER

在规范化之前,我最终得到下表。

标准化前

标准化后,我最终得到了这些表。

标准化后

但是,仍然没有什么能阻止我在EmployeeManager表格中意外地将在一个部门工作的经理分配给在不同部门工作的员工。

我发现的一种可能的解决方案是将 Department 放入EmployeeManager表中并定义引用完整性约束,以便在表中{Manager, Department}引用。{Employee, Department}EmployeeDepartment

EmployeeManager 表

但是,要使其正常工作不必{Manager, Department}是候选键吗?有没有不同的设计可以解决这个问题?

更新

好的回答我的第一个问题,不必{Manager, Department}是候选键吗?事实证明,{Manager, Department}表中的EmployeeManager不一定是候选键或唯一键。它只是必须是引用表{Employee, Department}中的外键EmployeeDepartment。key的唯一性{Employee, Department}没有很好的定义,并且在不同的引擎之间可能会有所不同。例如,MySQL 建议外键只引用唯一键。

此外,出于性能原因,MySQL 要求对引用的列进行索引。但是,系统不强制要求引用的列必须是 UNIQUE 或声明为 NOT NULL。对于 UPDATE 或 DELETE CASCADE 等操作,对非唯一键或包含 NULL 值的键的外键引用的处理没有明确定义。建议您使用仅引用 UNIQUE(包括 PRIMARY)和 NOT NULL 键的外键。

就我而言,它会起作用,因为员工只能在一个部门工作,但是如果限制机会允许员工在多个部门工作,它就不会起作用,因为{Employee, Department}将不再是唯一的。

它应该适用于所有情况,包括是否允许员工在多个部门工作的约束机会。

有没有不同的设计可以解决这个问题?我还考虑过用作为主键的表替换并返回到EmployeeDepartment带有列的前一个表。因此,现在要找出员工工作的部门,您需要加入表。ManagerDepartment{Manager}EmployeeManager(Employee, Manager)EmployeeManagerManagerDepartment

您是否发现此设计有任何不良做法或异常情况?

4

1 回答 1

0

假设所有这些列都被声明为 NOT NULL 。. .

我发现的一种可能的解决方案是将 Department 放入 EmployeeManager 表中并定义一个引用完整性约束,以便 {Manager, Department} 引用 EmployeeDepartment 表中的 {Employee, Department}。

是的,在“EmployeeManager”表中添加“department”列。但是您需要两个重叠的外键约束。(但见下文......)

  • (manager, department) 引用 EmployeeDepartment (Employee, Department)
  • (employee, department) 引用 EmployeeDepartment (Employee, Department)

由于 EmployeeDepartment.Employee 是唯一的,因此 EmployeeDepartment.Employee 和 EmployeeDepartment.Department 这对列也是唯一的。因此,您可以将“Employee”声明为主键,并这对列(Employee,Department)上声明唯一约束。如果需求发生变化并允许员工在多个部门工作,您可以删除单列主键。可能会同时删除主键约束和唯一约束,并创建一个包含两列的新主键约束,但严格必要的只是删除主键约束。

在像您这样的系统中,最好有一张经理表,其中包含明显的外键引用。现在,如果您删除员工 Will,您将失去 Steve 是经理的事实。

于 2014-05-14T02:03:13.747 回答