两个实体之间的多种关系,这是一种好的做法吗?

时间:2011-12-20 23:12:50

标签: mysql foreign-keys entity-relationship

关于办公室及其员工,我有以下典型情况:

  • 每位员工属于一个办公室
  • 每个办公室只有一名经理(一名工作人员)

ER模型

er http://img814.imageshack.us/img814/2204/capturefsi.png

正如您所看到的,这会导致关系被记录两次,一次是办公室表中的外键指向经理,也是指向工作人员工作的办公室的员工表。

我已经研究了这种建模的替代方法,但仍然有点迷失。请有人建议一种合适的建模方法,或者我的方法是否适用于该方案。

非常感谢

5 个答案:

答案 0 :(得分:2)

这不是“关系[被记录两次”],而是你在这些表之间实际上有两个关系 - 这是完全没问题的。我唯一担心的是,经理是否可以属于他所担任的经理所在的同一个办公室? (并且相关地说:每个工作人员是否有办公室并且每个办公室都有一名经理是工作人员?这是真的吗?)如果是这样,你有一个循环依赖:在办公室存在之前,您无法设置经理的办公室,但在经理存在之前,您无法设置办公室的经理。只要一个或另一个字段可以为空,您可以通过应用程序逻辑(INSERT一个,然后INSERT另一个,然后是UPDATE第一个)解决此问题,但它是一个有点难看。但如果这些是存在的关系,那么你就无法做到这一点。

答案 1 :(得分:1)

我可以,因为无论关系中的表是否相同,关系实际上都是非常不同的。你可以推断经理在她管理的办公室工作是正确的,但这是一个域规则,并没有使数据库设计的这一部分不规范化。 如果你想摆脱双重关系,你总是可以创建一个Managers表,其中包含Staff和Office的外键。

答案 2 :(得分:1)

从SQL的角度来看,这样的循环关系是有效的,但它会导致某些事情变得复杂。

例如,在备份和还原数据时,必须延迟创建其中一个外键约束,直到还原数据为止。因为如果在填写表之前创建约束,则在还原其办公室之前无法还原办公室的经理,并且在还原其管理员之前无法还原办公室。

另一种解决方法而不是使用Office.Manager外键列的方法是使用布尔列Staff.IsManager,对于经理来说是真的,但对于给定办公室中的所有其他员工都是假的。

答案 3 :(得分:0)

当您想要添加新办公室时,这似乎很尴尬。办公室必须有经理,所以你需要先让经理。但是经理是一名工作人员,必须有办公室,所以你需要先办公室。

要打破此循环,您需要允许一个暂时为NULL或其他一些不真实的值,然后修改您先创建的任何一个以引用第二个。并非不可能,只是尴尬。

如果我正在设计这个,我可能会有一个单独的“管理”表,将办事处与经理联系起来。

答案 4 :(得分:0)

这没关系,只是为了表明这种关系。但请注意,这可能会导致无限循环。

staffid ->officeid -> manager -> staffid

这个循环可能在检索数据时发生(我曾经遇到过相同的情况),因此最好将其标准化并避免这种双关系问题。