数据主键生成方式

来自: http://forum.javaeye.com/viewtopic.php?t=1071&postdays=0&postorder=asc&start=30

关于主键生成方式,主要有以下几种观点:
1、使用整数,键值在内存中;
2、使用整数,将键值保存到数据库中的一个表中;
3、使用UUID;

如果你对性能比较敏感,建议你不要使用UUID,一方面UUID的生成需要花一定的时间,另一方面,UUID的存储占用比整数更多的空间,对性能也很不利;
那么我们应该使用整数作为主键吗,答案是不确定的,要根据实际情况具体分析。
使用第一种方案,具有最高的效率,象Hibernate中的IncrementGenerator,由于hibernate本身就是跨数据库平台的,所以这种方式不用担心跨数据库平台的问题。但是第一种方案,不能应用在机群环境中。
第二种方式,能够应用机群环境中,向JBoss中的AutoNumber解决方案就是使用这种方式,但是这种方式也有很大的性能问题,当数据插入密集时,会导致冲突。
那么有没有一种高效率又能够应用在机群环境中的方案呢?
第一个方案具有最高的效率,但是不能应用在集群环境中,第二中方案能够应用在机群环境中,但是效率低。那么我们如果将这两种方案结合其来怎么样?那怎么结合呢?
我们来一起看一下这样的一个方案:我们知道对于第二种方案中,当要生成一个主键值时,系统会去读取并更新一次数据库中的表,相当于一次取值过程,每个主键值的生成都会有至少一次的数据库连接,而这正是性能瓶颈所在。为了解决这个问题,我们在每次“取值“时不是去出一个值,而是一次取出100个或更多,在每次需要生成主键值时,在内存中保存主键值的当前值和取值计数,当这个计数减小到0时,也就是前次取出的主键值已用完,这时再去数据库中取出100或更多的值。通过这种方式大大降低连接数据库的次数,减少冲突的可能性,可以大大提高第二中方案的性能问题,而且可以应用在机群环境中。
这种方案的取值部分,一般的都部署在一个EJB种,就像JBOSS中的AutoNumber,以进行事务隔离,防止主键更新事务与应用代码混在相同的事务中,当应用代码失败事务会滚时,将主键更新代码也回滚造成主键生成机制混乱。
当然这种方案也不是没有缺点,应该注意到,每次系统关闭时,都会造成一定的键值空当。大小与每次取值得个数有关。

在DudoJ框架中就实现了这种主键生成机制。DudoJ还实现了一个主键生成器,它是一个代理类,能够自动在第一种方案和最后一种方案间自动选择,已达到最好的性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值