【问题标题】:How to make multiple instances of foreign key work in one row如何使多个外键实例在一行中工作
【发布时间】:2017-04-24 09:43:21
【问题描述】:

大家好,各位 SQL 程序员。

我一直在尝试制定一个位于工业中的实景模型。 对数据库进行排序的客户端声明: 他的员工在多个不同的工作地点/办公室工作。每个工作场所/办公室都有一定数量的可以在这里工作的人——最少和最多。对于每个工作场所,都有一组人员,至少 2 人,最多 4 人。一次只能有一个小组驻扎在一个工作地点。该组还有一些规范,例如 - 其中没有领导者 - 每个人都是平等的。某个工人一次只能分配到一个组。并且历史上有证据证明谁在哪里工作以及工作了多长时间。

很长一段时间以来,我一直在尝试使用其属性来设计表格,但在我看来,到目前为止我所做的一切都存在一些严重的漏洞并且非常混乱。我非常感谢你们的任何反馈和建议。提前致谢。

【问题讨论】:

  • 向我们展示您的尝试,并描述其问题。
  • 基本上我按照客户的要求制作了表格:“工人”有(ID_W,Date_of_birth,Name,Surename),然后是“Work_place”(ID_W_P,地址,Pay_for_hour,Max_number_of_people,Min_number_of_people,类型)那么最后一个表“Shift / wok_goup”由(ID_W_G、Date、Start_of_Shift、End_of_Shift、Min_number_of_people、Max_number_of_people、Name)组成
  • 问题是我无法弄清楚如何使 Shift 中的人数范围从 2 到 4。所以问题将开始于我需要创建多个实例属于 Workers 表中的工人的外键多次(2 到 4 次)指向 Shift 表,在我看来这真的很混乱并且可能导致真正的问题,因为你可以有一个仅由 2 人组成的班次然后同时3或4人。如何使这项工作?

标签: sql database database-design foreign-keys foreign-key-relationship


【解决方案1】:

如果我理解正确,您有两个实体:employeeoffice。这些将需要两个表:

employee: id, name, whatever_else
office: id, desc, min_employees, max_employees, whatever_else

理论上这两个实体之间的关系是one-to-many,因为你说每个员工一次只能分配到一个办公室,所以你可以在employee表中添加一个office_id外键。

然而,必须跟踪历史意味着每个员工可能与办公室有多个关联,从而建立many-to-many 的关系。然后,您将需要另一个表来对其建模:

employeeOffice: employee_id, office_id, start_date, end_date

使用此模型,我想您需要执行的查询将非常容易;例如,找出每个办公室当前分配了多少员工

select  t1.id, t1.desc, count(distinct t2.employee_id)
from    office t1
join    employeeOffice t2
on      t1.id = t2.office_id
where   t2.end_date is null
group by t1.id, t1.desc

编辑

以这个样本数据为例

employee
id | name
1  | name1
2  | name2
3  | name3
4  | name4
5  | name5
6  | name6
7  | name7

office
id | desc
1  | office1
2  | office2

employeeOffice
employee_id | office_id | start_date   | end_date
1           | 2         | '01-01-2107' | '31-01-29107'
1           | 1         | '01-02-2107' |
2           | 1         | '01-01-2107' |
3           | 1         | '01-01-2107' |
4           | 1         | '01-01-2107' |
5           | 2         | '01-01-2107' | '01-03-2107'
6           | 2         | '01-01-2107' |
7           | 2         | '01-01-2107' |

这意味着员工 1 在办公室 2 工作了一个月,然后被分配到办公室 1。员工 5 两个月后辞职(或被解雇),因为他没有记录为空end_date

上面的示例查询将为您提供

id | desc    | count
1  | office1 | 4
2  | office2 | 2

【讨论】:

  • 非常感谢您的解释,但我得到了关系(或者我想我知道了),但我在查看 Worker-Shift 关系时遇到了更多麻烦。每个班次有 2 到 4 名工人,那么我将如何创建一个具有可变数量 Worker_ID 的行,每个工人都引用一个唯一的工人?
  • 你不要那样做。如果您有应用程序层,我会检查是否可以从那里将员工添加到班次(在插入之前计算已经分配了多少人),否则您可以使用在插入之前进行检查的触发器
  • 所以表格和你之前说的一样,好吗?然后是您提到的employeeOffice 表。但从我在该表中看到的情况来看,只有一名可能的工人被安置——还是我弄错了?因为我认为employee_id 需要在那里两次,或者这也是错误的吗?我只是想看看并考虑将数据插入其中以使行完整的方法-一开始我只需要在employeeOffice 表/Shift 表中的2 个工作人员,因为从你所说的我可以稍后添加它们。
  • 哦,我现在明白了。请原谅我的愚蠢,我如此专注于让 Worker_ID 成为轮班的一部分,以至于我忘记了我可以将它们分配到具有相同开始日期的同一个办公室。谢谢你的朋友,你让我大开眼界!
  • 很高兴它有帮助!如果此答案或任何答案解决了您的问题,请单击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
猜你喜欢
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
相关资源
最近更新 更多