【问题标题】:Achieving referential integrity in an Employee, Manager and Department relationship在员工、经理和部门关系中实现参照完整性
【发布时间】:2014-02-21 16:36:22
【问题描述】:

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

具有以下约束:

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

这张图说明了这个概念。

在标准化之前,我最终得到下表。

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

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

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

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

更新

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

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

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

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

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

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

【问题讨论】:

    标签: database database-normalization integrity referential


    【解决方案1】:

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

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

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

    • (经理,部门)引用 EmployeeDepartment(员工,部门)
    • (员工、部门)引用 EmployeeDepartment(员工、部门)

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

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

    【讨论】:

    • 啊,是的!我没有在 EmployeeManager 表中看到异常。这是否意味着它甚至不在2NF中?第二种解决方案是拥有一个 ManagerDepartment 表并使用 (Employee, Manager) 回到原来的 EmployeeManager 表更好吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多