我正在开发旅行管理应用程序。有问题的设计如下所示:
游览中的每个人都被指定为旅行者。
每个旅行者都有护照。
现在,旅行者可以是MainMember还是SubMember,具体取决于他是否是一家之主。
MainMember决定诸如TourPackage,其旅行家庭的总金额之类的东西。
子成员在旅行时依赖于主成员。因此,如果删除了MainMember,则还必须删除其所有SubMember。
所以,
旅行者有护照。 (一对一关系)
Traveler是MainMember或SubMember。 (一对零/一个在Traveler-MainMember和Traveler-SubMember之间)
一个MainMember可能有几个SubMember。 (一对多)
一个子成员只有一个主要成员。 (多对一)
我当前的ERD如下。
如您所见,这三个表-Traveler,MainMember和SubMember-形成了循环依赖关系。不过,我不确定是否会损害我的应用程序。
如果我删除作为MainMember的Traveler,则
1.旅行者记录被删除。
2.删除其相关的MainMember记录。
3.删除依赖于MainMember的SubMember记录。
4.子成员(member)的旅行者记录被删除。
虽然这似乎没有问题,但是删除Traveler-MainMember始终只会删除Traveler-SubMember(s)。不过,我对此仍然有不好的感觉。
谁能指导我进行更好的设计?
更新-
在等待答复时,我根据@Daveo的答复提出了另一种设计。基本上,Traveler包含自我引用的外键。子成员记录将使用它来识别其 parent 。
这是ERD。
现在,由于@Branko指出,在我以前的设计中没有循环依赖的问题,我想知道哪种设计更好?
另外,哪种设计最好通过Hibernate实现?我认为第二种方法在通过Hibernate实现时可能会导致复杂性。
我也希望了解一些有关您喜欢的设计的实现模式(Hibernate实体中的继承性等)的指针。
最佳答案
不,这不是循环依赖关系-此图中的“节点”无法通过沿其正确方向跟随图“边缘”到达自身1。它将更准确地描述为“合并”或什至(原始)“钻石形”依赖项。
不,这不会伤害您的应用程序。2
您将使用“每个表中的类”方法有效地实现继承(又名类别,子类,子类型,泛化层次结构等)。这种方法是干净的,但不能保证开箱即用的存在性3和排他性4。
amend it有很多方法可以实现,还有其他实现继承的实现策略,但是它们有自己的pros and cons。
在我看来,您的模型适合您要完成的工作,在应用程序级别强制存在/排他性可能比在数据库级别强制实现存在/弊端小。
1“方向”是从引用表到被引用表。 Traveller
既不引用MainMember
也不引用SubMember
,因此中断了循环。
2除非您使用的DBMS(例如MS SQL Server)不支持对此类“合并的”依赖项进行引用操作(在这种情况下,您需要通过触发器实现ON CASCADE DELETE)。
3 Traveller
不能单独存在(不能是“抽象”),它必须是MainMember
或SubMember
。
4 Traveller
不能同时是MainMember
和SubMember
。
关于database-design - 数据库设计-避免循环依赖,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14999131/