避免循环依赖

Jay*_*oot 6 database-design erd circular-dependency hibernate-mapping class-table-inheritance

我正在开发旅行管理应用程序.有问题的设计如下:

旅游中的每个人都被指定为旅行者.每位旅行者都有护照.现在,旅行者可以是主会员或子会员,具体取决于他是否是家庭主管.MainMember决定像TourPackage这样的东西,他的旅行家庭的总金额等.一个SubMember在旅行时依赖于MainMember.因此,如果删除了MainMember,则还必须删除其所有子成员.

所以,旅行者有护照.(一对一关系)旅行者是主会员或子会员.(Traveler-MainMember和Traveler-SubMember之间的一对一/一)MainMember可能有几个SubMembers.(一对多)子成员只有一个主要成员.(多到一个)

我目前的ERD如下.

旅行者ER图

如您所见,三个表 - Traveler,MainMember和SubMember - 形成了循环依赖.不过,我不确定它是否会伤害我的应用程序.如果我删除作为MainMember的Traveler,则1.删除Traveler中的记录.2.删除其相关的MainMember记录.3.删除依赖于MainMember的SubMember记录.4.删除子成员的旅行者记录.

虽然它似乎不是问题,但由于Traveler-MainMember删除将始终只删除Traveler-SubMember(s).不过,我对此感觉不好.

任何人都可以指导我更好的设计吗?

更新 -

在等待回复的同时,我根据@ Daveo的回复提出了另一种设计.基本上,Traveler包含自引用外键.SubMember记录将使用它来识别他们的父母.

这是ERD.

ERD与自我参考表

现在,正如@Branko指出的那样,我之前的设计中没有循环依赖问题,我想知道哪种设计更好?

另外,通过Hibernate实现哪种设计会更好?我认为第二种方法可能会在通过Hibernate实现时导致复杂性.

我还要感谢关于您喜欢的设计的实现模式(Hibernate实体中的继承等)的一些指示.

Bra*_*vic 5

如您所见,三个表 - Traveler,MainMember和SubMember - 形成了循环依赖.

不,这不是循环依赖 - 此图中的"节点"不能通过在正确方向1上跟随图形"边缘"来达到自身.它将被更准确地描述为"合并"或甚至(原型)"菱形"依赖.

不,它不会伤害您的申请.2

您正在有效地实现继承(也就是类别,子类化,子类型,泛化层次结构等),使用"单独表中的每个类"方法.这种方法很干净,但不能保证存在3和排他性4开箱即用.有一些方法可以修改它,并且还有其他的继承实现策略可以,但它们各有利弊.

在我看来,你的模型适合你想要完成的任务,并且在应用程序级别强制执行存在/排他性可能比在数据库级别尝试强制执行它的缺点更为邪恶.


1 "方向"来自参考表.Traveller不引用MainMember也不SubMember因此打破了循环.

2除非您使用的DBMS(例如MS SQL Server)不支持对此类"合并"依赖项的引用操作(在这种情况下,您需要通过触发器实现ON CASCADE DELETE).

3 Traveller不能单独存在(不能"抽象"),它必须是MainMemberSubMember.

4 Traveller不能同时MainMemberSubMember.