外键作为主键或仅将代理主键与 JPA 上下文中的外键不同
Posted
技术标签:
【中文标题】外键作为主键或仅将代理主键与 JPA 上下文中的外键不同【英文标题】:Foreign key as the primary key or just separate surrogate primary key different from foreign key in JPA context 【发布时间】:2012-07-31 08:40:05 【问题描述】:在 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)
【问题讨论】:
【参考方案1】:对于多对一关系,请始终使用您提出的第一个替代方案。
对于某些一对一的关系,可以合并表而不会产生不良影响。
第二个选择真正有用的地方是使用 class table inheritance model 实现超类-子类层次结构时,正如 Martin Fowler 所介绍的那样。在这种情况下,您希望保持子类表与超类表不同,以减少 NULL 的数量。但关系是一对一的。
通过使子类表中的 PK 和 FK 具有相同的键功能,并通过使 FK 引用超类表中的匹配条目,可以非常容易地将专用数据与通用数据连接起来,需要时。这可以称为“穷人的遗产”。
【讨论】:
【参考方案2】:在这种特殊情况下(1 到 0..1 的关系),请考虑将两个表合并为一个。
如果它们被有意拆分(例如,对于“垂直”分区),则首选相同的字段同时作为 PK 和 FK。
只有在可以将其变小时才考虑添加另一个键1,但要平衡这与额外索引的需要2,对@987654321的潜在敌意@ 3 并且需要对菱形依赖关系进行建模4。
1例如因为TABLE_2.TABLE_1_ID
是字符串,您可以将TABLE_2.ID
设为整数。
2每个新索引都会减慢 INSERT 的速度,并且可能会减慢 UPDATE 和 DELETE 的速度,具体取决于它们的 WHERE 子句。此外,任何额外的数据都会给缓存带来额外的压力,使其“更小”。
3聚簇表中的二级索引需要包含 PK 的副本,并且在定位行时会导致双重查找(首先是索引,然后是 PK)。 em>
4可能需要在“钻石”的两个“边缘”上使用识别关系,以确保钻石的“底部”引用单个 “顶”。
【讨论】:
【参考方案3】:我猜你正在寻找@MapsId
注释。
【讨论】:
以上是关于外键作为主键或仅将代理主键与 JPA 上下文中的外键不同的主要内容,如果未能解决你的问题,请参考以下文章