数据库设计问题。指向不同表的列值

Posted

技术标签:

【中文标题】数据库设计问题。指向不同表的列值【英文标题】:Database design issue. Column value pointing to different tables 【发布时间】:2016-08-23 08:59:59 【问题描述】:

我必须做什么的描述

我有一个应该与Table1 OR Table2 OR Table3 相关的table

例如,有一个表 Employees,它有: Id, Name, Address, Age, Salary, EmployerId

第二张表是RegisterEmployeeRequirementsId, RequirementType, EmployerId, EntryId.

其中需求类型可以是CreditStatusRequirementEmployeeDegreeRequirement)。

问题CreditStatusRequirement 包括CreditStatus它被收购的日期(检查它是否在去年)。我还有一个名为 CreditStatusRequirements 的附加表,其中包含列:

CreditStatus, DateTimeAcquired

另一方面,学位要求具有以下属性:DegreeName and MinGpa

为了解决这个问题,我创建了另一个具有这些属性的表。如果RegisterEmployeeRequirements 中的需求类型是CreditStatusRequirement,我将使用entryId 列查看CreditStatusRequirements 表,然后检查它是否完成。

否则,如果是EmployeeDegreeRequirement,我将使用entryId 列查看DegreeRequirements 表。我想使用像entryId 这样的列不是一个好习惯。

解决这个架构问题的方法是什么?

【问题讨论】:

如果对于您在 RegisterEmployeeRequirements 表中创建的每个条目,您还在 CreditStatusRequirement 或 EmployeeDegreeRequirement 中创建一个条目,那么您应该有一个外键关系船 CreditStatusRequirement -> RegisterEmployeeRequirements 和 CreditStatusRequirement -> RegisterEmployeeRequirements 即您应该删除 EntryId 列从 RegisterEmployeeRequirements 表中,并将 RegisterEmployeeRequirements 中的 Id 列作为 CreditStatusRequirement 和 EmployeeDegreeRequirement 表中的外键。 见***.com/questions/1654071/…; ***.com/questions/4050784/… 澄清基数,EmployeesCreditStatusRequirementEmployeesEmployeeDegreeRequirement 您需要概述所有三个参考表的外观。您还需要告诉我们通过将引用存储在一列而不是三列中获得了什么。 table1 table2 和 table3 是一些常见超类的子类吗? 【参考方案1】:

这很简单。 RegisterEmployeeRequirements 表中没有等效的 FK。将每个信用和学位要求详细信息表中的 FK 记录到 RegisterEmployeeRequirements。

像这样:

create table RegisterEmployeeRequirements(
  EmployeeId      int references ( ID ),
  RequirementType char( 1 ) not null,
  ..., -- Other common fields
  constraint PK_RegisterEmployeeRequirements primary key( EmployeeID, RequirementType ),
  constraint FK_RegisterEmployeeRequirements_Empe( EmployeeId )
    references Employees( ID ),
  constraint FK_RegisterEmployeeRequirements_Type( RequirementType )
    references RequirementTypes( ID ),
);

请注意,关键是员工 ID 和需求 ID 的组合。这确保了每个员工只能有两个定义的要求中的一个。我认为这符合您的数据库要求。

然后每个需求明细表可以这样定义:

create table CreditRequirements(
  EmployeeId int primary key,
  RequirementType char( 1 ) check( CreditType = 'C' ),
  Status     ...,
  Acquired   datetime,
  constraint FK_CreditRequirements_Emp foreign key( EmployeeID, RequirementType )
    references RegisterEmployeeRequirements( EmployeeID, RequirementType )
);

create table DegreeRequirements(
  EmployeeId int primary key,
  RequirementType char( 1 ) check( DegreeType = 'D' ),
  DegreeName varchar( 64 ),
  MinGPA     float,
  constraint FK_DegreeRequirements_Emp foreign key( EmployeeID, RequirementType )
    references RegisterEmployeeRequirements( EmployeeID, RequirementType )
);

只能为在 RegisterEmployeeRequirements 表中具有信用类型条目的员工创建信用详细信息表中的条目。 RegisterEmployeeRequirements 中学位类型条目的学位详细信息表也是如此。 RegisterEmployeeRequirements 中每种类型的需求最多只能插入一个,并且每个详细信息表中只能为每个员工插入一个条目。

您的数据完整性良好且设计可扩展。如果创建了第三种需求类型,则将类型条目插入到 RequirementTypes 表中,并为该类型创建一个新的详细信息表。现有表都不需要更改。

【讨论】:

非常感谢!!!我在设计中实现了几乎相同的模式。【参考方案2】:

为什么不直接使用单独的表格来记录学分状况和学位要求,而不再需要 RequirementType 列?

RegisterEmployeeCreditStatusRequirements 有: Id, EmployerId, CreditStatus, DateTimeAcquired

RegisterEmployeeEmployeeDegreeRequirements 有: Id,EmployerId,DegreeName,MinGpa

【讨论】:

以上是关于数据库设计问题。指向不同表的列值的主要内容,如果未能解决你的问题,请参考以下文章

基于不同表的行值对表中的列值求和

选择连接表的列值作为结果列名

显示2个不同实体表的数据表需要从数据库表中获取另一列值

在另一个表的 select 子句中使用一个表中的列值

如何用另一个表的列值更新一个表的列值? [复制]

事实表的数据仓库设计