【问题标题】:Database Design for the following Scenario以下场景的数据库设计
【发布时间】:2014-11-09 08:38:06
【问题描述】:

我正在为以下要求创建数据库架构: 员工具有一定的属性。这些相同的属性可以在作业中找到。 我需要做的是根据给定工作的属性搜索员工。例如,“为我查找与工作 id = 1 匹配且具有相同属性的所有员工”。 (用于搜索给定员工的所有工作的副 Versa)。这是我的数据库架构。

Job (
   jobId, 
   description
)

Employee(
  employeeId, 
  firstName, 
  lastName,
  startDate,
  email
)

Attribute(
   attributeId,
   description       
)

JobAttribute(
  jobId, (FK to Jobs.jobId)
  attributeId (FK to Attributes.attributeId)
)

EmployeeAttribute(
   employeeId, (FK to Employees.employeeId)
   attributeId (FK to Attributes.attributeId).       
)

查询“为我查找与作业 id = 1 匹配且具有相同属性的所有员工”。然后看起来像:

SELECT DiSTINCT e.employeeId 
FROM Employee e
INNER JOIN EmployeeAttribute ea
ON e.attributeId = ea.AttributeId
and e.employeeId = ea.employeeId
WHERE ea.AttributeId In (
Select ja.attributeId 
FROM Job j
inner join JobAttribute ja
    on j.jobId = ja.jobId
inner join AttributeTable at
    on ja.attributeId = at.attributeId
where jobId = 1
)
order by e.startDate asc

查询将返回至少有一个属性与工作相同的所有员工。

如果我需要根据使用此架构的作业返回分配了所有属性的所有员工,查询会是什么样子?

这是对查询性能的良好设计吗?我还想让它尽可能灵活,以允许以最少的代码更改添加新属性。

【问题讨论】:

  • 表名应该是单数; Employee 表包含 0 个或多个元组。
  • @duffymo 这纯粹是一个偏好问题。我不同意。表旨在成为元组的集合。因此,集合(表名)将是复数,但列名将是单数。话虽这么说,我不太明白你的评论,因为张贴的名字是单数。
  • 这里的东西被称为 EAV(实体属性值)。周围有很多人认为这种模式是有史以来最邪恶的事情。我认为这种模式有它的位置,并且在正确的情况下非常有用。这种模式的缺点之一是导致您重复加入属性表以获取所有值。
  • 您可能希望将您的需求转换为 ER 图,该图将清楚地显示实体及其关系,这反过来将有助于确定什么变成了表、派生表及其关系等。您的问题,Employees 和 Jobs 之间可能存在链接,而无需通过属性 - 如果是这样,设计就会改变。
  • 在我的要求中,只有当员工具有与该职位相关的属性时,他们才会与该职位相关联。因此,作为 FK 的工作中的员工 ID 是不可行的。 :(

标签: c# mysql sql sql-server database-design


【解决方案1】:

好的,您的第一个查询“找到所有匹配工作 id = 1 并具有相同属性的员工”,可以更简单如下

SELECT DISTINCT E.EmployeeId
FROM 
Employee E
INNER JOIN EmployeeAttribute EA ON (EA.EmpId = E.EmployeeId)
INNER JOIN JobAttribute JA ON (EA.AttributeId = JA.AttributeId)
WHERE AJ.JobId = 1

关于检索与给定工作的所有属性匹配的员工的查询

SELECT EA.EmployeeId, COUNT(EA.EmployeeId)
FROM EmployeeAttribute EA
INNER JOIN JobAttribute JA on EA.AttributeId = JA.AttributeId
WHERE JA.JobId = @jobId
GROUP BY EA.EmployeeId
HAVING COUNT(EA.EmployeeId) >= (SELECT COUNT(AttributeId) FROM JobAttribute J where J.JobId = @jobId)

您可能需要与 Employee master 一起获取该员工的其他详细信息。这两个查询都假定派生表上有一个 PK,它是两个 FK 的组合。

在性能方面,使用查询执行计划并相应地定义您的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多