我在急诊室发现了一个案例,在我的生命中,我无法找到如何实现参照完整性的方法。经典的员工、经理、部门关系可以说明这一问题。
具有以下约束条件:
员工只能在一个部门工作。
部门可以有很多员工。
员工可以有一个经理在同一个部门工作。
经理可以让许多员工在同一个部门工作。
没有经理的员工就是经理。
这个图说明了这个概念。
在正常化之前,我得到了下表。
正常化之后,我最终得到了这些表格。
但是,仍然没有什么能阻止我在EmployeeManager
表中将在一个部门工作的经理意外分配给在另一个部门工作的员工。
我发现一个可能的解决方案是将department放入EmployeeManager
表并定义一个引用完整性约束,以便{Manager, Department}
引用{Employee, Department}
表中的EmployeeDepartment
。
然而,要使其工作,不必将{Manager, Department}
作为候选密钥吗?有没有不同的设计可以解决这个问题?
更新
好的,回答我的第一个问题,{Manager, Department}
不一定是候选密钥吗?原来{Manager, Department}
表中的EmployeeManager
不一定是候选键或唯一键。它必须是引用{Employee, Department}
表中EmployeeDepartment
的外键。{Employee, Department}
键的唯一性没有很好地定义,并且可能在不同的引擎之间有所不同。例如,mysql建议外键只引用唯一的键。
此外,出于性能原因,mysql要求对引用的列进行索引。但是,系统不强制要求引用列是唯一的或声明为不为空的。对于诸如update或delete cascade之类的操作,对非唯一键或包含空值的键的外键引用的处理没有很好地定义。建议您使用只引用唯一键(包括主键)而不引用空键的外键。
在我的例子中,它将工作,因为员工只能在一个部门工作,但是如果限制允许员工在多个部门工作,它将不工作,因为{Employee, Department}
将不再是唯一的。
它应该在所有情况下都有效,包括约束是否有机会允许员工在多个部门工作。
有没有不同的设计可以解决这个问题?我还考虑了将EmployeeDepartment
替换为ManagerDepartment
表,将{Manager}
作为主键,并返回到以前的EmployeeManager
表中的(Employee, Manager)
列。因此,现在要了解员工工作的部门,您需要使用EmployeeManager
表加入ManagerDepartment
。
你认为这个设计有什么不好的做法或不正常的地方吗?
最佳答案
假设所有这些列都声明为非空。……
我发现一个可能的解决办法是把部门
employeemanager表并定义引用完整性约束,以便
{manager,department}引用了
EmployeeDepartment表。
是的,在“employeemanager”表中添加一列“department”。但是需要两个外键约束重叠。(但见下文。…)
(部门经理)推荐员工部门(员工,部门)
(员工,部门)参考员工部门(员工,部门)
由于employee department.employee是唯一的,因此employeedepartment.employee和employeedepartment.department列对也是唯一的。因此,可以将“employee”声明为主键,还可以对这对列(employee、department)声明唯一约束。如果需求更改并允许员工在多个部门工作,则可以删除单列主键。我可能会同时删除主键和唯一约束,并创建一个包含这两列的新主键约束,但严格来说,所需的只是删除主键约束。
在像您这样的系统中,通常最好有一个包含明显外键引用的经理表。现在,如果你删除员工遗嘱,你就失去了史蒂夫是经理的事实。
关于database - 在员工,经理和部门关系中实现参照完整性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21939990/