当前位置: 首页 > 面试题库 >

为什么建议避免在外键上进行单向一对多关联?[重复]

孔皓
2023-03-14
问题内容

在Hibernate在线文档中,在7.2.3节“一对多”中提到:

外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。您应该使用联接表进行这种关联。

我想知道为什么?我唯一想到的是,它可能会在级联删除期间产生问题。例如,“人”是指外键上一对多关系上的地址,并且该地址将拒绝在该人之前被删除。

谁能解释建议背后的合理性?

以下是参考文档内容的链接:7.2.3。一对多

我已将实际内容复制粘贴到此处:

外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。

<class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses">
        <key column="personId"
            not-null="true"/>
        <one-to-many class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>
create table Person (personId bigint not null primary key)
create table Address (addressId bigint not null primary key, personId

bigint not null)

您应该使用联接表进行这种关联。


问题答案:

外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。

这有两个方面:

  • 单向
  • 一对多

该线程
@CalmStorm 的答案被删除的链接地址只有这些东西的第二位,但让我们开始吧。

该线程建议用联接表替换一对多关系,因为否则,一对多方法“用不属于该实体的列填充许多副表,仅用于“链接” porpuses(原文如此)
‘。这种策略可能会在Hibernate层中产生干净的模型,但不幸的是,这会导致数据库损坏。

因为SQL只能断言子记录有一个父记录;没有办法强制父母必须有孩子的规则。因此,没有办法坚持要求表在联接表中具有条目,其结果是有可能具有孤立的子记录,这正是外键旨在防止的。

我还有其他一些反对意见,但下一个最重要的反对意见是不适当。相交表旨在表示多对多关系。用它们表示一对多的关系会造成混乱,并且我喜欢过多的其他数据库对象。

因此,第二个方面是: 单向
一对多关联。这些问题是Hibernate默认处理它们的特殊方式。如果我们在同一事务中插入父项和子项,则Hibernate插入子项记录,然后插入父项,然后使用父项的键更新子项。这需要可延期的外键约束(yuck!),也可能需要不可延期的非null约束(double
yuck)。

有两个解决方法。一种是使用双向的一对多关联。根据文档中的引用,这是最常见的方法。另一种方法是调整子对象的映射,但这有其自身的影响。



 类似资料:
  • 问题内容: 在Hibernate联机文档中,在7.2.3节“一对多”下提到: 外键上的单向一对多关联是一种不常见的情况,因此不建议这样做。您应该使用联接表进行这种关联。 我想知道为什么?我唯一想到的是,它可能会在级联删除期间产生问题。例如,“人”是指外键上一对多关系上的地址,并且该地址将拒绝在该人之前被删除。 任何人都可以解释该建议背后的合理性吗? 这是参考文档内容的链接:7.2.3。一对多 我已

  • 问题内容: 在本文档中(向下滚动至“单向”部分): http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity- mapping-association- collections 它说,与联接表进行单向一对多关联比仅在拥有实体中使用外键列更可取。我的问题是,为什么它更受欢迎? 问题答案: 考

  • 我使用的是PlayFramework 2.3,我有以下类: MyEntity.java: Version.java 当我想为实体创建一个新版本时,我通过分离复制它,将id设置为0,并按如下方式持久化: 如果我使用下面的代码,它工作正常(第一个代码) 我不太喜欢这个代码,因为我可以像这样使用它(第二个代码) 但如果我这样做,外键不会在“实体”表中更新,我不知道为什么。有人能告诉我克隆的两种实现方式有

  • 但是,我似乎搞错了一些事情,因为当Hibernate创建表时,会创建多个外键,如下所示: 信息:HHH10001501:从JdbcConnectionAccess[org.hibernate.engine.jdbc.env.internal.jdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@5E5595F3]获得的用于(

  • 问题内容: 我有一个,我需要能够对列进行重新排序。但是,我希望第一列不能重新排序。我使用以下命令来启用重新排序: 现在可以对列进行重新排序,包括不需要的第一列。有什么方法可以锁定第一列? 我已经看到一些使用两个表的解决方案,其中第一列在单独的表中,但是也许有更好/更简单的方法。 问题答案: 我认为您需要重写中的方法。在类有一个方法,你应该能够看到,以确定它是否是你的固定列,然后你应该能够取消事件。

  • 问题内容: 我正在为表生成代理键,由于我的hi / lo算法,每次重新启动/重新启动计算机时,可能会出现间隙。 从主键或索引内部结构的角度来看,序列中没有间隙为什么很重要?我问这是为了更深入地了解mysql。 问题答案: 从主键或索引内部结构的角度来看,为什么在序列中没有空缺很重要? 这并不重要-是什么让您相信呢? 与主键有关的所有事情是,它对于表中的所有数据都是唯一的。值是什么,或前后的记录是否