8

我正在开发一个旅行管理应用程序。有问题的设计如下所示:

旅行中的每个人都被指定为旅行者。每个旅行者都有一本护照。现在,Traveler 可以是 MainMember 或 SubMember,这取决于他是否是一家之主。MainMember 决定诸如 TourPackage、他的旅行家庭的总金额等内容。SubMember 在旅行时依赖于 MainMember。因此,如果 MainMember 被删除,它的所有 SubMember 也必须被删除。

所以,旅行者有护照。(一对一关系) Traveler 是 MainMember 或 SubMember。(Traveler-MainMember 和 Traveler-SubMember 之间的一对零/一)一个 MainMember 可能有多个 SubMember。(一对多)一个 SubMember 只有一个 MainMember。(多对一)

我目前的 ERD 如下所示。

旅行者 ER 图

如您所见,三个表 - Traveler、MainMember 和 SubMember - 形成了循环依赖关系。不过,我不确定这是否会损害我的申请。如果我删除一个作为 MainMember 的 Traveler,那么 1. Traveler 中的一条记录被删除。2、删除其相关的MainMember记录。3、删除依赖于MainMember的SubMember记录。4. 子会员的旅行者记录被删除。

虽然这似乎不是问题,但作为 Traveler-MainMember 删除将始终只删除 Traveler-SubMember。不过,我对此有不好的预感。

谁能指导我更好的设计?

更新 -

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

这是 ERD。

带有自引用表的 ERD

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

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

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

4

2 回答 2

6

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

不,这不是循环依赖 - 此图中的任何“节点”都无法通过沿正确方向1跟随图“边”到达自身。它可以更准确地描述为“合并”甚至(原始)“菱形”依赖。

不,它不会损害您的应用程序。2

您正在使用“单独表中的每个类”方法有效地实现继承(又名类别、子类化、子类型化、泛化层次结构等)。这种方法是干净的,但不能保证开箱即用的存在3和排他性4 。有一些方法可以修改它,也有其他的继承实现策略可以,但它们各有优缺点

在我看来,您的模型非常适合您尝试完成的任务,并且在应用程序级别执行存在/排他性可能比在数据库级别执行它的弊端要小。


1 “方向”是从参考到参考表。Traveller不引用MainMember也不SubMember因此打破循环。

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

3 Traveller不能单独存在(不能是“抽象的”),它必须是MainMemberor SubMember

4 Traveller不能同时是MainMemberSubMember

于 2013-02-21T13:16:58.833 回答
1

我只会在数据库中有两个表。

旅行者和密码

Traveler 将有一个 Parent_Id 字段,该字段将链接回 Traveler 表并存储主要/主要旅客是谁。还存储此表中主/子成员的通用字段,如联系电话

然后使用继承和 ORM 在您的实际应用程序中创建两个不同的类。MainMember 和 SubMember MainMember 将是 Traveler 中 Parent_Id 为空的所有行 SubMember 将是 Traveler 中 Parent_Id 不为空的所有行

于 2013-02-21T10:05:14.743 回答