ejb3:用简单的主键映射多对多关系

Posted

技术标签:

【中文标题】ejb3:用简单的主键映射多对多关系【英文标题】:ejb3: mapping many-to-many relationship jointable with a simple primary key 【发布时间】:2010-09-13 10:47:07 【问题描述】:

我经常在书中看到,当多对多关系转换为数据库模式时,JoinTable 会获得一个复合键,该键由多对多关系中涉及的表的主键组成。 我尽量避免使用复合键。因此,我通常甚至为 JoinTable 创建一个代理键,并允许数据库通过触发器或数据库具有用于递增主键的任何功能来填充它。这似乎是一种更简单的方法。

我能想到的唯一问题是,JoinTable 中的外键对可能重复。但这可以通过在 JoinTable 中插入一行之前的简单查询来避免。

由于书籍总是使用复合键方法,我想知道如果我对 JoinTable 使用简单的一列代理键是否有任何负面影响?

【问题讨论】:

【参考方案1】:

在我看来,使用单个主键是个坏主意。

首先,正如您所说,单个主键不能确保数据库中的唯一性。当然,您可以在运行时使用一个简单的查询来检查它,但这很昂贵,而且如果您只忘记一次进行检查查询,您可能会使您的数据库处于不一致的状态。

另外,我认为在这种情况下,没有必要为主键使用附加列。您不需要通过唯一主键来识别关系,因为该关系已经由两个唯一键定义:两个表的主键。在这种情况下,您将拥有不必要的数据,这会增加您的数据模型的复杂性,而且您可能永远不会使用这些数据。

【讨论】:

该查询并不昂贵..,它只搜索相关行。但是,是的,忘记这将是一个问题。谢谢,我想您的论点为使用复合键提供了坚实的优势。我还在这里找到了一篇相关文章:***.com/questions/38870/…【参考方案2】:

我尽量避免使用复合键。

嗯?为什么?我的意思是,为什么完全避开它们?这背后的原因是什么?

所以我通常会为 JoinTable 创建一个代理键,并允许数据库通过触发器或数据库用于递增主键的任何功能来填充它。这似乎是一种更简单的方法。

没有冒犯,但我们对简单性的定义不同。实在看不出哪里更简单了。

我能想到的唯一问题是,JoinTable 中的外键对可能重复。但这可以通过在 JoinTable 中插入一行之前的简单查询来避免。

首先,不要使用 SELECT 来检查唯一性(您可以有竞争条件,不锁定整个表的 SELECT 不会保证任何事情),使用 UNIQUE 约束,这就是 UNIQUE 的用途。

让我们想象一下 SELECT 是可能的,你真的觉得这更简单吗?一般来说,如果可能,人们会尽量避免访问数据库。他们还避免了做额外的工作。

由于书籍总是使用复合键方法,我想知道如果我对 JoinTable 使用简单的一列代理键是否有任何负面影响?

所以你的意思是这样的:

   A              A_B                 B
-------      ------------------    --------
ID (PK)      ID (PK),              ID (PK)
             A_ID (FK),
             B_ID (FK),
             UNIQUE(A_ID, B_ID)   

当然,您可以这样做(如果您使用某种触发器或标识列作为 ID,您甚至可以将其映射到 JPA)。但我不明白这一点:

    上述设计不是映射 (m:n) 关系的标准方法,它不是人们习惯于查找的。​​li> A_B 本身并不是一个真正的实体(这是模型以某种方式暗示的,参见 #1)。 这对 (A_ID, B_ID) 是密钥的自然候选者,为什么不使用它(而且浪费空间)? 上述设计并不更简单,它确实引入了更多复杂性。

总而言之,我没有看到任何优势。

【讨论】:

以上是关于ejb3:用简单的主键映射多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 映射及查询

hibernate对象关系实现多对多实现

mybatis一对一关联关系映射

Hibernate多对多关系映射(建表)

Hibernate的多对多关联关系

JPA的一对多,多对多用法