Moh*_*din 4 database-design relations
我一直在寻找一个很好的资源,其中循环依赖得到了很好的解释,不幸的是没有找到好的资源。因此,我试图确切地了解我应该避免哪种循环依赖。问题是我发现了一些以矛盾方式解释的资源。有人可以准确解释一下我们应该避免哪些类型的循环依赖(以及为什么)?
以这些关系为例:
这里提到这种关系是不好的(我不明白为什么)。
但是,这里提到了相同的关系不是问题(并被描述为非循环):
Models <--------------------------- SuperSets
^ ^
| |
| |
Tasks <---------------------------- Sets
Run Code Online (Sandbox Code Playgroud)
另一个例子是这样的:
我也不明白为什么这是一个循环关系?
在我看来,以前的所有关系都不是曲线(箭头方向不会回到同一点)。我认为我对循环依赖项的理解有问题。有人可以为我解释一下,特别是在前面的例子中吗?
在任何这些情况下都没有循环。在“循环引用”场景中,您有“鸡和蛋的问题”——无法在表中插入一行,因为它总是缺少对其他表的引用,例如:
用户 {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
,那么你可以将它们添加到ProjectAssignment
并ProjectTeam
表,但你必须保持现有的AKs
(唯一的)和外键引用它们适用。
注意 PK = 主键 AK = 备用键(唯一) 所有属性(列)NOT NULL