坏循环依赖的定义是什么?

Moh*_*din 4 database-design relations

我一直在寻找一个很好的资源,其中循环依赖得到了很好的解释,不幸的是没有找到好的资源。因此,我试图确切地了解我应该避免哪种循环依赖。问题是我发现了一些以矛盾方式解释的资源。有人可以准确解释一下我们应该避免哪些类型的循环依赖(以及为什么)?

以这些关系为例:

在此处输入图片说明

来源

这里提到这种关系是不好的(我不明白为什么)。

但是,这里提到了相同的关系不是问题(并被描述为非循环):

Models <--------------------------- SuperSets
   ^                                    ^
   |                                    |
   |                                    |
Tasks  <---------------------------- Sets
Run Code Online (Sandbox Code Playgroud)

来源


另一个例子是这样的:

在此处输入图片说明

来源

我也不明白为什么这是一个循环关系?

在我看来,以前的所有关系都不是曲线(箭头方向不会回到同一点)。我认为我对循环依赖项的理解有问题。有人可以为我解释一下,特别是在前面的例子中吗?

Dam*_*vic 5

在任何这些情况下都没有循环。在“循环引用”场景中,您有“鸡和蛋的问题”——无法在表中插入一行,因为它总是缺少对其他表的引用,例如:

用户 {user_id, address_id, ...}
  PK {user_id}

外键 {address_id} 参考地址

——
——
地址 {address_id, user_id, ...}
     PK {address_id}

外键 {user_id} REFERENCES 用户

那篇文章的作者唯一的问题是不了解数据库设计。他的示例中的问题只是糟糕的设计,源于坚持单列 PK (ID),并且不了解业务逻辑如何与 DB 约束相关联。

在第二个例子中,他的设计根据用户和产品分配转销商佣金,而不是根据实际购买,这在商业上没有意义。在第一个示例中,可以将用户分配到其项目范围之外的任务;再次与“循环”无关,但不知道如何实现约束。


对于第二个示例,您可以考虑以下内容:

产品 {ProductID}
     PK {产品 ID}

客户 {CustomerID}
     PK {客户 ID}

经销商{ResellerID}
     PK {ResellerID}

——
——
购买 {PurchaseID, CustomerID, ProductID, ResellerID, ...}
      PK {购买 ID}

外键 {CustomerID} 参考客户
外键 {ProductID} 参考产品
外键 {ResellerID} 参考 经销商

如果你坚持Commission表,说如果不是每次购买都涉及转售商。

产品 {ProductID}
     PK {产品 ID}

客户 {CustomerID}
      PK {客户 ID}

经销商{ResellerID}
      PK {ResellerID}

——
——
购买 {PurchaseID, CustomerID, Product_ID, ...}
      PK {购买 ID}

外键 {CustomerID} 参考客户
外键 {ProductID} 参考产品


——
——
佣金 {PurchaseID, ResellerID, ...}
        PK {购买 ID}

外键 {PurchaseID} 参考 购买
外键 {ResellerID} 参考 经销商

对于第一个示例:

项目 {ProjectID, ...}
     PK {项目ID}

用户 {UserID, ...}
  PK {用户 ID}

任务类型 {TypeID, ...}
      PK {TypeID}

项目角色 {RoleID, ...}
         PK {角色 ID}

——
——
任务 {TaskID, ProjectID, TypeID, ...}
  PK {TaskID}
  AK {任务 ID,项目 ID}

外键 {ProjectID} 参考项目
外键 {TypeID} 参考任务类型

——
——
项目团队 {用户 ID、项目 ID、角色 ID、...}
         PK {用户 ID,项目 ID}

外键 {UserID} 参考用户
外键 {ProjectID} 参考项目
外键 {RoleID} 参考 ProjectRole

——
——
项目分配 {UserID, ProjectID, TaskID, ...}
               PK {用户 ID、项目 ID、任务 ID}

外键 {UserID, ProjectID} 参考项目团队
外键 {TaskID, ProjectID} 参考任务

如果你喜欢单柱PKs,那么你可以将它们添加到ProjectAssignmentProjectTeam表,但你必须保持现有的AKs(唯一的)和外键引用它们适用。

注意 PK = 主键
     AK = 备用键(唯一)
     所有属性(列)NOT NULL