我正在开发一个数据库来保存随叫随到的时间表的信息。目前我的结构看起来像这样:
Table - Person: (key)ID, LName, FName, Phone, Email
Table - PersonTeam: (from Person)ID, (from Team)ID
Table - Team: (key)ID, TeamName
Table - Calendar: (key dateTime)dt, year, month, day, etc...
Table - Schedule: (from Calendar)dt, (id of Person)OnCall_NY, (id of Person)OnCall_MA, (id of Person)OnCall_CA
我的问题是:使用计划表格,我应该保留结构原样,其中dt是唯一键,或者我应该重新排列它这样dt是非唯一的,表格如下所示:
Table - Schedule: (from Calendar)dt, (from Team)ID, (from Person)ID
并且每天都有多个条目, OR 只需使用就可以了:
Table - Schedule: (from Calendar)dt, (from PersonTeam)KeyID - [make a key ID on each of the person/team pairings]
一个团队总是会有人随叫随到,但是一个人可以一次接听多个团队(如果他们在多个团队中)。
如果完全不同的设置可以更好地让我知道!
感谢您的帮助!如果我的问题不清楚,我道歉。我学习速度很快,但每天使用SQL仍然相当新,所以我想确保我在学习时使用最佳实践,这样我就不会养成坏习惯。
答案 0 :(得分:2)
当前版本,每个团队一列,可能不是一个好主意。由于您将团队表示为一个表(而不是枚举或等效表),这意味着您希望随着时间的推移添加/删除团队。这将迫使您向表中添加/删除列,这总是比添加/删除几行更大的任务。
第二个选项是解决此类问题的常用方法。一个安全的选择。您始终可以从Schedule(teamID,personID)到PersonTeam定义其他外键约束,以确保您不会错误地将计划任务分配给不属于该团队的人员。
第三个选项与第二个选项非常相同,只是您将PersonTeam的复合自然键交换为代理简单键。由于所述复合密钥的两个组件已经是代理,因此添加这个附加密钥没有优势(就不变性等而言)。此外,它将变成一个非常简单的N-M关系(PersonTeam),大多数数据库管理员/ ORM将很好地处理成一个更复杂的对象,需要自己管理。
通过Occam的剃刀,我会取消额外的代理键并使用你的第二个选项。
答案 1 :(得分:1)
在我看来,答案可能取决于团队数量是否固定和相当小。当然,团队的名称是否固定也可能很重要,但这可能与列命名有关。
更具体地说,我的观点是:
如果业务要求总是要有一个小而固定数量的人(比方说三个),那么在Schedule
中分配三个列可能会更方便,每个队伍要保留一个指定人员的身份证明,即您当前的结构:
dt OnCall_NY OnCall_MA OnCall_CA
--- --------- --------- ---------
以dt
为主键。
如果团队数量(在Team
表中)也是固定的,您可以在列名中包含团队名称/指示符,就像您现在所做的那样,但是如果团队数量超过三个并且只有Schedule
中的团队数量限制为三个,那么您可以使用OnCallID1
,OnCallID2
,OnCallID3
之类的名称
但即使这个要求得到修复,它也可能只会变成今天的 ,明天你的老板说:“我们不再与固定数量的团队合作(随叫随到)”,或者“我们需要将支持的团队数量扩大到四个,我们可能需要在未来进一步扩展”。因此,更普遍的方法是您正在考虑在您的问题中切换到的方法,即
dt Team Person
--- ---- ------
其中主键现在为dt, Team
。
通过这种方式,您可以轻松扩展/减少数据库级别的通话人数,而无需更改架构中的任何内容。
<强>更新强>
我忘了在原来的答案中解决你的第三个选项(抱歉)。到此为止。
你的第一个选择(目前实际实施的选项)似乎暗示每个团队只能由一个人(不超过一个人)出席。如果您将代理人ID分配给人员/团队对并使用Schedule
中的这些密钥而不是Person
和Team
的单独ID,则您可能无法强制执行上述“一个人”每个团队在数据库级别的计划“要求(或者,至少,这可能有点麻烦)”,而使用单独的密钥,将Team
设置为复合密钥{{}的一部分就足够了1}}并且你已经完成了,现在每天不超过一个团队。
此外,如果一个人更改团队,如果他们在团队中的存在以这种方式得到了解决,即对{/ 1}}人员/团队进行(dt, Team)
的引用,则可能会遇到困难对。您可能需要更改Schedule
表中的团队参考,这会导致错误地表示历史信息:当在某一天查看回电话的人时,显示的人员团队将是他们所属的人员。 现在,而不是他们当时的那个。
另一方面,为PersonTeam
中的人员和团队使用单独的ID可让您自由更换团队,提供您不当然,请Schedule
引用(Schedule.Team, Schedule.Person)
。