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