带循环引用的数据库模型,可以避免吗?

时间:2014-10-01 03:02:49

标签: database-design software-design object-model

我有以下表格:

  • 成员
  • person_membership(人与会员之间的多对多)
  • 关系

现在,一个人可以是一个或多个成员资格。每个人都可以与会员中的另一个人相关。

为了完成上述工作,我将以下字段放在关系表中:

  • ID
  • person1_id
  • person2_id
  • membership_id

正如您所看到的,上述内容最终会在会员关系之间形成循环引用。有没有办法或更好的设计来避免这种情况?

例: John和Marry的会员资格是1234 约翰和亚当的会员资格为5678

在1234会员中,John是Marry的丈夫

在会员5678中,约翰是亚当的兄弟

1 个答案:

答案 0 :(得分:2)

在关系数据模型中没有技术原因可以避免循环引用。 SQL处理得很好,如果它们是相同类型的实体,那么相应地对关系进行建模以表示同一表中的实体是一种好习惯。在某些数据库风格中甚至还有特殊的关键字来支持递归/层次关系。

如果它让你感到不舒服,只需习惯在SQL查询中对表进行别名,例如当你因不同原因(在不同级别)访问Person表时,表示访问级别。

换句话说,假设Person有一个父字段。每个Person记录将以递归方式指向父记录。

select Children.*, Parent.name from person Children
  left join person Parents
    on Children.parentID = Parents.ID

现在就好像您正在选择并加入两个不同的表格。 SQL并不关心在查询中引用同一个表的次数,它每次都将它视为一个唯一的表(为了我所说的目的)。您可以选择Person作为p1,p2,p3,p4等,然后根据需要将它们全部加入。

如果你试图摆脱循环引用而出现的问题是无数的,取决于未来的要求,而且它们通常表现不佳。由于缓冲区缓存局部性,单个Person表将表现良好。如果您试图将Person表分解为不同的功能角色,那么您不可避免地遇到需要多个表中的同一个人的一些要求,并且最终会复制数据。

视图是简化循环引用的另一个有用工具,具体取决于您是否可以为Person分配角色或记录类型标识符。在许多情况下,视图可以按功能对基表进行切片/过滤。