当存在三个实体时,称为什么关系,Table1
Table2
以及Table3
Table1
与 具有一对一关系 与Table3
Table2
具有一对多关系 与Table3
Table3
具有两个复合键,Table1ID
并且Table2ID
.
这种关系叫什么?我试图弄清楚如何在 ORM 中对此进行建模,但因为我什至不知道这种关系是什么,我什至不知道从哪里开始。
当存在三个实体时,称为什么关系,Table1
Table2
以及Table3
Table1
与 具有一对一关系 与Table3
Table2
具有一对多关系 与Table3
Table3
具有两个复合键,Table1ID
并且Table2ID
.
这种关系叫什么?我试图弄清楚如何在 ORM 中对此进行建模,但因为我什至不知道这种关系是什么,我什至不知道从哪里开始。
我们通常将其称为reflexive或 bi-directional。
在 ORM 中处理这一点并非易事。
如果您可以Table1ID
从中删除列Table3
(删除指向后面的外键),那将简化模型。但这可能不是您的选择。
Hibernate 将此称为双向关联;Hibernate 只保留该关联的一个“结束”;它不会在两个方向上维护外键。
编辑
我查看了模型图(来自您在评论中提供的链接)。
看起来很像该personVehicle
表是一个关联表,介于person
和之间vehicle
。这与我们在解决多对多关系时看到的模式相同。您的模型看起来像是多对多的特殊情况,其中关系的一侧被限制为仅一侧。
就键而言,您的模型如下所示:
person
id PK
vehicle
id PK
personVehicle
person_id PK, FK->person(id)
vehicle_id PK, FK->vehicle(id)
如果我理解您的要求,您希望在表上表示一个外键约束,该约束vehicle
指向 personVehicle 表中的一行:
vehicle
id PK, FK->personVehicle(vehicle_id)
vehicle
我不知道有任何 ORM 会自动为您在表中维护这种类型的双向外键。(我不认为在外键列中维护值是不可能的,不仅仅是可能以 ORM 将在两个方向上维护外键的方式“声明”这种关联。
(某些数据库,例如 Oracle,允许我们创建和维护这样的关系,方法是在我们插入、更新和删除时允许外来约束被延迟,并将外键约束的检查推迟到 COMMIT 之前。)
如果有一个外键 fromvehicle
指向 in 中的一行personVehicle
,并且要求 in 中的行personVehicle
必须引用回表中完全相同的行vehicle
(而不仅仅是某行),那么你真的不需要表中的外键vehicle
。该关系已经在模型中由personVehicle
表中的外键充分表示。
如果您需要强制执行车辆最多可以与一个 personVehicle 相关的约束,则需要对 UNIQUE 约束personVehicle(vehicle_id)
。这充分代表了模型中的需求。
如果这确实是一对一的,并且您需要一个外键,那么这实际上相当于vehicle
完全删除该表,并将该表中的属性合并到 personVehicle 表中。
编辑
我对反身一词的使用可能不正确。我通常将具有对同一表中的列的外键引用的表称为递归表。
就两个表之间的关系而言,每个表都有指向另一个表的外键......只是任何行,但回到引用它的完全相同的行......我认为这是“反映”回来的关系。
关系反映回来。但我们不使用术语“反射”,因为该术语在 Java 中具有特殊含义。因此,也许唯一合适的术语是“双向”。
典型的双向一对一关系是一个表中的行指向另一个表中的行,该行又指向原始表中的完全相同的行:
例如:
t1 t2
id t2_id id t1_id
--- ----- ---- ------
1 A A 1
2 B B 2
3 C C 3
另一种形式是行不一定引用引用它的同一行。(这通常不限于一对一),但我们仍然有指向两个方向的外键(从 t1 到 t2,从 t2 到 t1)
例如:
t1 t2
id t2_id id t1_id
--- ----- --- ----
1 A A 2
2 B B 3
3 C C 1
在第一种情况下,我们有一个要求,其中一行有一个外键值,它只引用另一个表中引用原始行的行。关系“反映”回来。
在第二种情况下,我们没有这个要求。如果我从第 1 行开始,它指向 A 行,A 行又指向第 2 行。
在定义数据库中的外键关系方面,约束的定义是相同的。区别通常在于外键列是否可以为 NULL,或者必须为 UNIQUE。
我认为除了“双向”之外,还有一个术语可以将第一种情况与更一般的第二种情况区分开来。我以为我使用了“反身”或“反思”这个词,但我可能弄错了。
就“递归”关系而言,外键指向同一个表中的一行,该外键(几乎)总是引用表中的不同行;它不引用自身。