Database design 避免循环依赖

Database design 避免循环依赖,database-design,hibernate-mapping,circular-dependency,erd,class-table-inheritance,Database Design,Hibernate Mapping,Circular Dependency,Erd,Class Table Inheritance,我正在开发一个旅行管理应用程序。所讨论的设计如下所示: 旅游中的每个人都被指定为旅行者。 每个旅行者都有护照。 现在,旅行者可以是主要成员,也可以是次要成员,这取决于他是否是一家之主。 主要成员决定旅游套餐、旅行家庭的总金额等。 子成员在移动时依赖于主成员。因此,如果一个main成员被删除,那么它的所有子成员也必须被删除 所以, 旅行者有护照。(一对一关系) 旅行者是主要成员或子成员。(一对零/出行者主成员和出行者子成员之间为一) 一个主成员可以有多个子成员。(一对多) 子成员只有一个主成员。(

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

旅游中的每个人都被指定为旅行者。 每个旅行者都有护照。 现在,旅行者可以是主要成员,也可以是次要成员,这取决于他是否是一家之主。 主要成员决定旅游套餐、旅行家庭的总金额等。 子成员在移动时依赖于主成员。因此,如果一个main成员被删除,那么它的所有子成员也必须被删除

所以, 旅行者有护照。(一对一关系) 旅行者是主要成员或子成员。(一对零/出行者主成员和出行者子成员之间为一) 一个主成员可以有多个子成员。(一对多) 子成员只有一个主成员。(多对一)

我目前的ERD如下

如您所见,三个表——Traveler、MainMember和SubMember——形成了一个循环依赖关系。不过,我不确定这是否会影响我的申请。 如果我删除了一个主要成员,那么 1.来自Traveler的记录被删除。 2.其相关的主要成员记录被删除。 3.依赖于MainMember的子成员记录将被删除。 4.子成员的出行者记录被删除

虽然这似乎不是问题,但作为Traveler主成员,delete将始终只删除Traveler子成员。不过,我对此有一种不好的感觉

有谁能指导我找到更好的设计吗

更新-

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

这是ERD

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

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


对于您喜欢的设计,我还希望您提供一些关于实现模式(Hibernate实体中的继承等)的建议。

我在数据库中只有两个表

旅行者和密码

Traveler将有一个Parent_Id字段,该字段将链接回Traveler表,并将存储主要/主要Traveler是谁。 还存储此表中主/子成员的公共字段,如联系人号码

然后使用继承和ORM在实际应用程序中创建两个不同的类。 主成员和子成员 MainMember将是Traveler中父项Id为空的所有行 子成员将是Traveller中父项Id不为null的所有行

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

不,这不是一个循环依赖关系-此图中的任何“节点”都不能通过沿着其正确方向1的图“边”到达自身。它将更准确地描述为“合并”甚至(原型)“菱形”依赖

不,这不会影响您的应用程序

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

在我看来,您的模型对于您正试图实现的目标来说是很好的,在应用程序级别强制实现存在/独占性可能比在数据库级别强制实现它的缺点要小


1“方向”是指从参照表到参照表
Traveler
不引用
Main成员
子成员
,因此会中断循环

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

3
traveler
不能单独存在(不能是“抽象的”),它必须是
main成员
子成员


4
Traveler
不能同时是
main成员
SubMember

对main成员和SubMember(extensing Traveler)@guido使用继承-实际上,这是我在实现POJO实体时的想法。但是,这如何解决数据库设计中的循环依赖性呢?或者我误解了你的说法。如果您能详细解释一下,我将不胜感激。请看一下第二种设计:如果您要为主出行者和次出行者提供单独的表格,为什么不利用它并正确地建模它们之间的关系,这样就不会有两个次出行者或两个主出行者连接起来?从
traveler
traveler
的循环引用(这次是真实的;)不遵守这些限制。我认为@Daveo的想法是将所有3个traveler表合并为一个,这将是实现继承的“同一个表中的所有类”方法,是的,会导致大量空值,但也可能有一些优势(请参阅我答案中的链接)。“但这种方法效率很低”-在某些情况下效率较低,而在另一些情况下效率更高。无论哪种方式,你都会有妥协,唯一的问题是你认为在你的特殊情况下什么是更好的折衷。就我个人而言,我建议您坚持您最初的方法,除非您确定了不这样做的具体原因。但是这种方法最终会在single Traveler表中出现大量空值。主成员有6个特定特征,子成员有2个。因此,对于SubM,main成员列将保持为null