休眠中索引和@NaturalId之间的区别
Posted
技术标签:
【中文标题】休眠中索引和@NaturalId之间的区别【英文标题】:Difference between indexing and @NaturalId in hibernate 【发布时间】:2017-07-29 23:25:55 【问题描述】:有一些关于自然标识符的文章,我在那里读到自然标识符促进了对休眠中最常用字段的查找。 In this post,他们描述了自然标识符对于使用特定字段查找任何数据要好得多。他们还描述了自然标识符由 hibernate 索引,hibernate 通过使用该索引来提高查找性能。
据我所知,还有一些方法可以为特定字段创建索引,使用这种方式可以获得查找性能。那么使用自然标识符比一般索引有什么优势呢?
例如,我可以创建一个具有适当索引的实体类,例如,
@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;
------------
根据定义,两者都以相同的方式工作,并且都在后台使用索引方法。那么从技术上讲,索引和自然标识符之间有什么区别?推荐哪种方法以及它比另一种更好?
【问题讨论】:
【参考方案1】:当您使用@NaturalId 时,Hibernate 将维护自然 id 到主键的映射。例如,如果您有如下的 User 实体:
//This is pseudo-code
User
@Id
long id;
@NaturalId
String username;
Hibernate 将存储哪些用户名映射到哪些 id,这意味着如果一个实体已经与会话对象关联,Hibernate 可以通过自然 id 从会话中加载它。 (此功能也可以扩展到二级缓存)。
索引将创建一个附加列,以使原始索引列的所有行保持排序顺序。可以对索引列进行二分查找,以减少查找时检查的行数。
我相信唯一约束会自动索引 Postgres 中的相应列。我个人同时使用唯一约束和自然 id 注释。
【讨论】:
非常感谢。正如你所说,自然标识符比索引有一些额外的好处,而索引比自然标识符有一些额外的重载。那么,你想推荐什么?我应该使用自然标识符并使用索引离开吗? 两者并不相互排斥。在加载对象时,Hibernate 在内部使用 NaturalId。 Index 注释在模式创建期间使用。如果您的模式是由 Hibernate 生成的,那么当 Hibernate 看到 Index 注释时,它将为该列(在数据库中)创建一个索引。对于经常查询的唯一字段,我建议使用@naturalid 和@column(name="...", unique=true)以上是关于休眠中索引和@NaturalId之间的区别的主要内容,如果未能解决你的问题,请参考以下文章