2013-04-26 97 views
0

我有一个名为Tbl_Event的表,用于存储即将发生的事件的基本信息。两个表之间的多个外键

Tbl_Event 

EventID Description Location 

我有我创建了一个新的表

tbl_Event_Staff 

    RecordID StaffID EventID 

,STAFFID另一个表叫工作人员,存储人员信息

Tbl_Staff 

StaffID Name 

现在每个事件可以有多个职员,为实现这一和EventID对它们有一个COMBINED唯一约束。 有一个附加条件,其中一名工作人员需要成为活动的主管。什么是最佳的解决方案来实现这一目标,我应该在tbl_event添加一个额外的列 - SupervisorID

Tbl_Event 

EventID Description Location SupervisorID 

并将其链接到tbl_Event_Staff上,STAFFID(在这种情况下,将是这两个表之间的外键 - 事件ID和StaffID)

或 *我不认为这是冗余数据的最佳解决方案。

我应该向tbl_Event_Staff - isSupervisor(bool)添加一个额外的列,并且每行都有一个布尔变量,表示该EVENT的员工是否为主管。

tbl_Event_Staff 

    RecordID StaffID EventID IsSupervisor 
     1  10  3   true 
     2  20  3   false 
     3  30  3   false 

是否有其他解决方案?

回答

1

我会使用第二种方法,并且,但是可能的话,会在该表上设置约束,使得每个EventID只有一个行可以是主管。

如何做到这一点的细节因数据库而异 - 在某些系统中,可能必须使用触发器强制执行。 - 有没有理智的理由使用前缀在SQL区分对象类型 - 语法

CREATE UNIQUE INDEX ON EventStaff (EventID) WHERE IsSupervisor = 1 

我也建议与tbl_前缀废除:在SQL Server,它可以使用筛选指标完成的语言意味着你可以纯粹通过它在查询中的位置来告诉对象的类型 - 除了一种情况。

我提到的情况是视图和表可能会出现在查询中的相同位置并且无法区分。然而,这是一个好的事情 - 一般来说,你不应该在意你正在处理的对象是一个表还是一个视图 - 数据库开发者应该可以自由地创建一个不同的表结构并重新创建旧的结构使用原始表格中的视图 - 现有查询不应受到影响。

+0

感谢您的输入。这是解决此问题的最佳方法吗?我将拥有大量冗余数据,并且更新数据库将会困难得多。虽然,每当用户将职员设置为主管时,都会想到它,但我可以遍历该事件的所有staffID,并将IsSupervisor标志设置为false,但是该表不会被正常化。猜这就是我必须付钱的价格。 – 2013-04-26 06:41:43

+0

@ Abhi.Net - 好吧,到目前为止你有两个答案,我们不同意。以此为标志,说明没有“最佳方法”。只有您知道您需要从这些数据结构中支持哪些查询和操作。而且,正如我在旁边指出的那样,您可以(从任一设计中)构建模仿其他设计的视图 - 因此,如果稍后决定其他结构更合适,则可以重新构建它,然后只需重新编写这些视图查询从重新设计中受益。 – 2013-04-26 06:44:55

+0

多数民众赞成我认为,我强调要获得最佳解决方案的唯一原因是,这是ER图分配的一部分,我需要创建一个数据库结构并规范化它。除了这部分以外,一切都完成了,我不确定采用哪种方法,但我可能会选择第二种,然后留下评论来解释我的选择。 – 2013-04-26 06:47:51

1

第一种解决方案更好,因为它可以自动防止您创建具有多个主管和/或具有多个主管的事件的事件:当事件的supervisor_id列不可为空时,您的RDBMS可确保每个主管有一个主管事件。

如果你需要得到与true/false指标标志着主管一表的形式你的结果,你可以随时通过加入到Tbl_Event,并比较Tbl_Event.supervisortbl_Event_Staff.StaffID得到这一结果。

+0

但在列与外键之间建立外键关系并不是主键?在tbl_event和tbl_event_staff中,staffid和supervisorID都是非关键属性。 – 2013-04-26 03:21:52

+0

@ Abhi.Net我不会将它链接到'tbl_Event_Staff',我会直接将它链接到'Tbl_Staff',其中'StaffID'是主键。 – dasblinkenlight 2013-04-26 03:26:28

+0

我其实也考虑过这个问题,但在这种情况下,我可以在tbl_staff的工作人员标识中添加staffId,而tbl_staff_event中没有记录。这意味着员工在事件中作为主管工作,但在tbl_staff_event中没有记录。 – 2013-04-26 03:33:19