有一些关于自然标识符的文章,我在那儿读到,自然标识符可以提高对休眠中最常用字段的查找。 In this post,他们描述了自然标识符对于使用特定字段查找任何数据要好得多。他们还描述了自然标识符是由休眠索引的,而休眠通过使用该索引来提高查找性能。

据我所知,还有一些方法可以为特定字段创建索引,并使用这种方法可以获得查询性能。那么,使用自然标识符比常规索引有什么优势?

例如,我可以创建一个具有适当索引的实体类,例如,

@Entity
@Table(name = "users", indexes = {
    @Index(columnList = "username", name = "users_username")
})
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

我可以通过其他方式创建没有索引但具有自然标识符的实体,例如,
@Entity
@Table(name = "users")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @NaturalId
    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

根据定义,两者都以相同的方式工作,并且都在后台使用索引方法。那么从技术上讲索引和自然标识符之间有什么区别?推荐哪种方法,它比另一种更好?

最佳答案

当您使用@NaturalId时,Hibernate将维护自然ID到主键的映射。例如,如果您有一个类似于以下的用户实体:

//This is pseudo-code

User {
@Id
long id;

@NaturalId
String username;
}

Hibernate将存储哪些用户名映射到哪些ID,这意味着如果一个实体已经与会话对象关联,则Hibernate可以通过自然ID从会话中加载它。 (此功能也可以扩展到第二级缓存)。

索引将创建一个额外的列,该列将原始索引列的所有行保持在已排序的顺序中。可以在索引列上执行二进制搜索,以减少为查找而检查的行数。

我相信唯一约束会自动为Postgres中的相应列建立索引。我个人使用唯一约束和自然ID注释。

10-07 13:21
查看更多