简体   繁体   中英

Difference between indexing and @NaturalId in hibernate

There have some article on natural identifier and I read there that natural identifier boosts lookup for mostly used fields in hibernate. In this post , they described that natural identifier is far more better for looking up any data using a particular field. They also described that natural identifier is indexed by hibernate and hibernate boosts lookup performance by using that index.

As far I know there have also some way to create index for a particular field and using this way lookup performance can be earned. So what is the advantage of using natural identifier over general indexing?

For an example I can create an entity class having proper indexing like,

@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;

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

}

Other way I can create an entity having no indexing but natural identifier like,

@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;

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

}

By definition both are working in same way and both are using indexing approach under the hood. So technically what is the difference between indexing and natural identifier? Which is recommended approach and how it's better over another?

When you use @NaturalId, Hibernate will maintain a mapping of the natural ids to primary keys. For example, if you have a User entity like the following:

//This is pseudo-code

User {
@Id
long id;

@NaturalId
String username;
}

Hibernate will store which usernames map to which ids, which means if an entity is already associated with the session object, Hibernate can load it from the session by natural id. (This capability can also be extended to the 2nd level cache).

Indexing will create an additional column that keeps all of the rows of the original indexed column in a sorted order. Binary search can be conducted on the indexed column to reduce the number of rows examined for a look up.

I believe unique constraints automatically indexes the corresponding column in Postgres. I personally use both unique constraint and natural id annotations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM