在两个子表之间约束多对多表

Ing*_*als 5 normalization database-design

这个交流网站的新手,所以我希望我的问题不是不合适的。

创建一个有点标准化的数据库 我有一个设计问题,我不确定如何有效地处理。

一张表与另外两张表具有一对多关系。这两个表然后在它们之间具有多对多关系。我不应该以某种方式确保(除了在编程插入中)链接在一起的项目属于同一个父表。

让我们把它放在一个场景中(这是一个虚构的场景):

部门表,其中每一行是公司中的一个部门。它与 Employee 表具有一对多关系。因此,每个员工都属于一个且仅一个部门。

Division 表还与记录了特定项目的 Project 表具有一对多关系。该项目还必须注册员工在此特定项目中记录的小时数。我会使用 Employee 和 Project 之间的多对多表和一个小时列来做到这一点。

这应该一切正常(我认为至少),除了理论上数据库中没有任何内容可以确保 Employee 和 Project 属于同一个部门,即使它们应该并且实际上都属于该表中的一个实体。

有什么好方法可以确保这种模式的意图和数据的完整性由一些抽象的关系数据库处理。您会以任何其他方式构建数据库还是会对多对多关系施加一些限制?

Nic*_*mas 3

为什么从事项目的员工必须严格属于拥有该项目的同一部门?这听起来更像是一个业务规则,您可以将其留给应用程序来执行,而不是需要DRI 的规则。

但假设您需要使用 DRI 强制执行此操作。您说您有一个将员工与项目关联起来的多对多表。假设您使用的是 SQL Server,您可以按如下方式扩展此表:

CREATE TABLE dbo.Employee_Project (
     ProjectID            INT
   , ProjectDivisionID    INT

   , EmployeeID           INT
   , EmployeeDivisionID   INT

   , Hours                INT

   , CONSTRAINT FK_Project FOREIGN KEY (ProjectID, ProjectDivisionID) 
        REFRENCES dbo.Project(ProjectID, DivisionID)

   , CONSTRAINT FK_Employee FOREIGN KEY (EmployeeID, EmployeeDivisionID) 
        REFERENCES dbo.Employee(EmployeeID, DivisionID)

   , CONSTRAINT CK_EmployeeProjectSameDivision CHECK (ProjectDivisionID = EmployeeDivisionID)
);
Run Code Online (Sandbox Code Playgroud)

这是这里发生的事情:

  • 我们这里有两个复合外键,一个用于 Employee,一个用于 Project,因此我们可以在同一个表中拥有两个实体的 DivisionID,并由 DRI 保证正确。
  • 这些复合外键需要UNIQUE引用表上的索引。因此,除了这些表中 EmployeeID 和 ProjectID 上的主键之外,您还需要 (EmployeeID, DivisionID) 和 (ProjectID, DivisionID) 上的唯一键。
  • CHECK 约束保证员工只能分配到同一部门拥有的项目。

如果您想查看此设计模式的另一个示例,这是我对具有类似要求的设计问题给出的答案。