【发布时间】: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