外键作为主键或仅与JPA上下文中的外键不同的单独代理主键

时间:2012-07-31 08:40:06

标签: database-design jpa foreign-keys primary-key shared-primary-key

在JPA上下文中使用FK作为PK,或使用代理PK和FK作为FK的最佳做法是什么? 我看到很少有人说他们必须将FK映射为PK,因为他们有遗留数据库。所以这意味着对于新表,如果你有控制来创建它们,最好使用以下结构:

TABLE_1
-------
ID (PK)
...

TABLE_2
-------
ID (PK) 
TABLE_1_ID (FK)

而不是:

TABLE_2
-------
TABLE_1_ID (PK) and (FK)

3 个答案:

答案 0 :(得分:1)

对于多对一关系,请始终使用您提供的第一个替代方案。

对于某些一对一的关系,这些表可以合并而不会产生不良影响。

当您的第二个替代方案真正变得有用时,使用class table inheritance model实现超类子类层次结构,如Martin Fowler所示。在这种情况下,您希望保持子类表与超类表不同,以减少NULLS的数量。但这种关系是一对一的。

通过在子类表中创建与PK和FK相同的键功能,并通过使FK引用超类表中的匹配条目,使得将特定数据与通用数据连接变得非常容易,什么时候需要这可以称为“穷人的遗产”。

答案 1 :(得分:0)

在这种特殊情况下(1到0..1的关系),考虑将两个表合并为一个。

如果它们被故意分割(例如用于“垂直”分区),则选择相同的字段为PK和FK。

如果你可以把它变得更小 1 ,只考虑添加另一个密钥,但要平衡需要额外的索引 2 ,对clustering <的潜在敌意sup> 3 需要模拟菱形依赖 4


1 例如因为TABLE_2.TABLE_1_ID是字符串,您可以生成TABLE_2.ID整数。

2 每个新索引都会减慢INSERT的速度,并且可以根据WHERE子句减慢UPDATE和DELETE的速度。此外,任何额外的数据都会给缓存带来额外的压力,使其“变小”。

3 群集表中的辅助索引需要包含PK的副本,并且在定位行时可能导致双重查找(首先是索引,然后是PK)。

4 在“钻石”的两个“边缘”上使用识别关系可能是必要的,以确保钻石的“底部”引用单个 “顶部”。

答案 2 :(得分:0)

我猜您正在寻找@MapsId注释。