我在ER中找到了一个案例,对于我的生活,我无法弄清楚如何实现参照完整性。经典的员工,经理,部门关系可以说明这个问题。
具有以下约束条件:
此图说明了这一概念。
在规范化之前,我最终得到下表。
归一化后,我最终会得到这些表格。
但是,仍然没有什么可以阻止我意外地将在一个部门工作的经理分配给在EmployeeManager
表中不同部门工作的员工。
我找到的一个可能的解决方案是将Department放入EmployeeManager
表并定义参考完整性约束,以便{Manager, Department}
在{Employee, Department}
表中引用EmployeeDepartment
。< / p>
但是,要实现这一点,{Manager, Department}
是否必须成为候选键?是否有不同的设计可以解决这个问题?
好的回答我的第一个问题,{Manager, Department}
不必是候选键吗?事实证明,{Manager, Department}
表中的EmployeeManager
不必是候选键或唯一键。它只需是引用{Employee, Department}
表中EmployeeDepartment
的外键。 {Employee, Department}
密钥的唯一性没有很好地定义,并且可能在不同引擎之间有所不同。例如,MySQL建议外键仅引用唯一键。
此外,MySQL要求出于性能原因对引用的列进行索引。但是,系统不强制要求引用的列为UNIQUE或声明为NOT NULL。对于诸如UPDATE或DELETE CASCADE之类的操作,没有很好地定义对非唯一键或包含NULL值的键的外键引用的处理。建议您使用仅引用UNIQUE(包括PRIMARY)和NOT NULL键的外键。
在我的情况下它会起作用,因为员工只能在一个部门工作,但是如果约束机会允许员工在许多部门工作,那么它将不起作用,因为{Employee, Department}
将不再是唯一的。 /秒>
它应该适用于所有情况,包括约束机会允许员工在许多部门工作。
有不同的设计可以解决这个问题吗?我还考虑将EmployeeDepartment
替换为ManagerDepartment
表,并将{Manager}
作为主键,然后返回到包含EmployeeManager
列的上一个(Employee, Manager)
表。现在,要找出一个员工工作的部门,您需要将EmployeeManager
加入ManagerDepartment
表。
您是否看到此设计存在任何不良做法或异常情况?
答案 0 :(得分:0)
假设所有这些列都声明为NOT NULL。 。 。
我找到的一个可能的解决方案是将部门纳入 EmployeeManager表并定义一个引用完整性约束 {经理,部门}指的是{员工,部门} EmployeeDepartment表。
是的,为&#34;部门&#34;添加一列到&#34; EmployeeManager&#34;表。但是你需要重叠的两个外键约束。 (但见下文......)
由于EmployeeDepartment.Employee是唯一的,因此EmployeeDepartment.Employee和EmployeeDepartment.Department列对也唯一。所以你可以宣布&#34;员工&#34;作为主键,还在列对(Employee,Department)上声明唯一约束。如果需求发生变化并允许员工在多个部门中工作,则可以删除单列主键。 I 可能会删除主键和唯一约束,并创建包含两列的 new 主键约束,但所有这些都严格必要是删除主键约束。
在像你这样的系统中,拥有一个管理员表通常是一个好主意,具有明显的外键引用。现在,如果你删除员工威尔,你就会失去史蒂夫是经理的事实。