如何在关系数据库中对 1:N 关系实施总参与约束?

How do I enforce a total participation constraint on 1:N relationship in a relational database?

Employee_Department_ER

在此示例中,实体部门由许多员工管理,每个部门必须参与这种关系(双线表示全部参与)。实体员工可以管理一个部门,每个员工可以参与也可以不参与这种关系。

我想知道将其映射到数据库中的关系模式的正确方法是什么。我在 Google 和其他帖子上做了一些搜索,但他们的回答仍然让我感到困惑。一种方法是使用

Employee(<attrs_for_employee>, department_id) // department_id is a foreign key that refers to Department's primary key
Department(<attrs_for_department>)

这种方法清楚地显示了 1:N 关系,但我没有看到部门的任何整体参与(部门可能由员工管理,也可能不由员工管理)。

如果我们改为扩展 Department,

Department(<attrs_for_department>, employee_id)
Employee(<attrs_for_employee>

这种方法显示部门的总参与度,但失去了 1:N 关系。

是否有正确的方法来显示 1:N 和关系模式的总参与度?是否有必要创建一个新模式 Employee_Department 来合并两个主键,就像在 M:N 关系中一样?

使用数据库触发器。这里的诀窍是“一个部门必须由一名或多名员工管理”不能直接在模型本身中表示。它必须符合逻辑。最好的逻辑在触发器中。您的供应商产品的确切代码会有所不同,但逻辑是这样的:

  • 在 DEPARTMENT 上放置一个 BEFORE INSERT 触发器。

  • 在该触发器中,获取传入 INSERT 的 EMPLOYEE_ID。

  • 去 EMPLOYEE table.

    中找到
  • 如果存在,请插入。

  • 如果不是,则抛出消息说必须先添加一个EMPLOYEE,并且要在DEPARTMENT中插入的记录中必须使用这样一个员工。

  • 在 EMPLOYEE 上放置一个 BEFORE DELETE 触发器。这是为了确保您以后不会孤立该部门。

  • 在该触发器中,确保 DEPARTEMENT 至少有两个 EMPLOYEE,这样您要删除的不是最后一个。

  • 如果两个以上,让DELETE通过。

  • 如果只有一个,抛出一个错误提示你不能删除最后一个员工。

明确地说,有许多规则必须在代码中强制执行,而不能在模型中强制执行。触发器是必经之路。

如果您使用的平台无法很好地执行触发器或根本无法执行触发器,则必须按计划在存储过程 运行 中或在独立代码(例如 Python、Java 等)和 运行 的时间表。触发器对于数据规则来说很神奇!