Protogalaxy

Planet #0

PHSS-Core开发日志#4 再谈主键策略

在PHSS的设计初期,由于数据库设计经验·的不足以及对于数据库跨表ID唯一性的需求,在一番查询之后我选择了UUID作为整个系统的ID类型。但是在实际代码编写的过程中,由于采用了基于JPA的Hibernate Bootstrap方式,在fetching的时候需要使用JPA提供的基于EntityManager的·fetch方法,比如EntityManager.find()与EntityManager.createQuery()。但不尽如人意的是,在主键采用UUID类型的情况下,JPA所提供的Fetching方法出现了不可预知的问题:在UUID具体值已确定的条件下,使用entitymanager.find()方法通过UUID进行fetching,即使UUID正确,也会出现entity无法找到的问题,尝试两种fetching方式后都无法定位,并且Google和Stackoverflow查询未果后,最终还是决定更换主键策略。在更加深入地研究了各种主键策略之后,发现自己以前对数据库主键的理解还是存在一些问题,所以在这里重新总结一下关于数据库主键策略选择的各种要点。

主键类型:

1.自增int

数据库自带的整形自增id,具有较高的性能,缺点是可定制性比较低。

2.Generator生成的Unique ID

由开发者自定义的Generator生成的唯一ID,用于其可定制性,可以根据需求定制其长度,唯一性,生成性能等属性。缺点是开发起来比较麻烦。

3.UUID

全称为通用唯一识别码(Universally Unique Identifier),由一组32位的16进制数构成,具有很大程度的唯一性,一般用于分布式系统,用来保证id的跨数据库唯一性。缺点是由于长度的关系会占用很大的系统空间,并且在一些数据库中会造成额外的性能开销。

4.GUID

UUID的一种变种,由微软公司研发。

在JPA规范中,主键的生成策略一般有以下几种:

1.Table

在此策略下,持久化引擎会使用关系型数据库的一个Table来生成主键,优点是可移植性较好。

2.Sequence

调用某些数据库,比如Oracle中内置的序列(Sequence)机制来生成主键。

3.Identity

使用一个Identity列来生成主键

4.Auto

将主键的生成策略交给持久化引擎来决定,从Table,Sequence,Identity中选择合适的主键生成策略。

 

发表评论