我正在 JPA 中使用
@MapsId
注释将外键 (FK) 映射到主键 (PK)。根据@MapsId注解,FK和PK具有相同的值。然而,当我检查数据库模式时,我注意到索引是仅为 PK 创建的。
示例:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Post post;
}
我的问题:
索引FK和PK:既然在这种情况下id既是PK又是FK,难道不应该有一个共享索引同时充当PK和FK索引吗?
不必要的索引:由于FK和PK相同,是否需要为FK添加额外的索引,否则会多余吗?
最佳实践:在此场景中处理索引以确保最佳性能且无冗余的最佳实践是什么?
附加信息:
数据库:我正在使用
MsSQL
、MySQL
、Oracle
。
观察: 目前,只为PK创建索引,数据库模式中没有明确为FK创建单独的索引。由于PK和FK是相同的,我不想为FK添加额外的不必要的索引。对此的最佳解决方案是什么?
任何有关如何处理这种情况的见解或建议将不胜感激。谢谢。
https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/
通过
ID
既是 PK 又是 FK,我假设您的意思是您有另一个超类型表,其中 ID
是 also PK,并且所讨论的表是共享相同密钥的子类型。如果是这种情况,您的 FK 会限制子类型使用超类型中存在的 ID
。
FK 不是索引 - 它是一个规则,如果要插入的
ID
不在父/超类型表中,则防止在表上插入/更新。子表上的 FK(不一定)不涉及任何索引。 parent 表需要一个索引(一个 unique 索引,事实上,通常是 PK,但也可能是 UK)。但定义FK约束的子表却没有。现在,在具有 FK 的列上添加索引通常是一个非常好的做法,因为这将加快父表上的删除速度(在允许删除之前,父表必须检查子表中是否有任何孤立值,这是非常大的)借助索引),但这不是必需的,并且不会仅仅因为您定义了 FK 就自动创建。
但是,在您的情况下,
ID
已经因您的 PK 而被编入索引。您无需进一步对其进行索引。