论坛首页 Java企业应用论坛

为了方便以后在各种数据库间移植,采用那种主键生成方式最好...

浏览 53018 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-08-15  
第一个问题我的理解是uuid的序号向后移动了,而不是数据区的物理位置,降低效率的原因应该是出在索引上面的
第二个问题,当出现赃数据的时候,我们往往会通过检索
查错的,没有人回去看海量数据的,可是前台的错误信息
会替你诊断错误数据的范围的
0 请登录后投票
   发表时间:2004-08-15  
这里有几个帖子,但是不代表我的观点,我也是长期受网上的一些观点得出自己的结论的,没有敢在大型应用中实际测试,所以只敢说是观点的
http://www.winnetmag.com/Windows/Article/ArticleID/8434/8434.html
http://sphear.demon.nl/weblogs/wellink/archive/2004/03/15/598.aspx
我也只是随便找了几个网页,希望大家可以充分讨论的
0 请登录后投票
   发表时间:2004-08-15  
willmac 写道
这里有几个帖子,但是不代表我的观点,我也是长期受网上的一些观点得出自己的结论的,没有敢在大型应用中实际测试,所以只敢说是观点的
http://www.winnetmag.com/Windows/Article/ArticleID/8434/8434.html
http://sphear.demon.nl/weblogs/wellink/archive/2004/03/15/598.aspx
我也只是随便找了几个网页,希望大家可以充分讨论的


这两篇文章我粗略的浏览了一下:

第一篇讲的是在SQL Server下面对于让SQL Server自动生成uniqueidentifier数据类型的时候作者自己出现的错误,实质上作者讲的是他自己用错了一个SQL Server的功能,和我们讨论的主题没有什么关系。

第二篇讲的是让使用SQL Server数据库的时候,使用uniqueidentifier数据类型的主键,并且用uniqueidentifier数据类型的主键做聚簇索引的时候可能出现的性能问题,只能说在特定的数据库的特定的场景下,用特定的数据库的特定数据类型的时候出现的性能问题,这和我们讨论的主题仍然没有什么关系。更何况就是这个问题也是很有争议性,并没有肯定的结论,你看他文章下面就有很多反对的意见了。

所以你仍然没有说服我用UUID有什么不妥的地方。何况UUID和GUID也不完全是一回事。Hibernate的UUID是Java程序来生成unique ID,不是数据库来生成unique ID。
0 请登录后投票
   发表时间:2004-08-15  
robbin 写道
引用
UUID的存储占用比整数更多的空间,对性能也很不利


考虑到当前的海量存储硬件,这点空间占用实在算不了什么。至于性能很不利的说法,能不能给个理论依据,或者实际测试报告。我想不出来用char类型做主键,性能损失有如此巨大的任何理由。

我还不太清楚Hibernate是否实现了你在dudo说的那种主键生成策略,不过要在Hibernate中实现这种策略也是易如反掌的事情。

其实我认为在数据库应用中,极其频繁的操作往往都是查询,至于频繁的insert应用实在太罕见,就算有,也不是O/R Mapping适用的场合。所以在主键生成策略上过于追究性能的细节,没有太大的意思。


     正因为hibernate中IncrementGenerator是在内存中保存当前的键值,所以明确说明了IncrementGenerator不能应用于集群环境中,在单机环境中IncrementGenerator有很高的效率。当然还包括了其他的几个生成器。有兴趣可以看一下源代码。

   至于UUID的效率,不同的UUID生成机制效率相差很大,hibernate中的UUID机制效率还是可以的,但是与IncrementGenerator相比,差别不在一个数量级,我的测试是IncrementGenerator可以在10ms之内生成1000个,但是UUID要生成1000个值需要200到300ms,当然了,平均到每个值的时间是不值得一提的,但是可以肯定这两种方式效率差别很大。
   其实UUID的空间存储大点算不了什么,但是它会影响到数据库的数据缓存,影响查询的命中率,最重要的是他会影响到索引的效率。如果在一个大的项目中,使用较多的UUID对系统没有好处。如果有好的整数主键解决方案,还是使用整数的解决方案好。
   UUID的好处是使用方便,你可以在任何地方都可使用,如果你要使用整数的解决方案,那你可能只能在框架中使用,因为如果不在框架中使用,要自己控制生成主键是很困难的。
0 请登录后投票
   发表时间:2004-08-15  
讨论UUID的生成效率是没有意义的,你生成UUID的速度再慢,也要比随后的数据库insert的速度快至少1个以上数量级。插入数据库记录的时候,速度的瓶颈在于数据库IO,而不是在Hibernate一端UUID的生成速度。

引用
它会影响到数据库的数据缓存,影响查询的命中率,最重要的是他会影响到索引的效率


为什么会影响缓存,影响命中率?说说道理。 影响索引效率又为什么?
0 请登录后投票
   发表时间:2004-08-16  
数据库对频繁的使用到的数据库记录在内存中都会有缓存,如果字段的占用的空间多相比之下,缓存的记录数就会少,当然查询的命中率(缓存中找到记录的几率)就低了。

  数据库对于整数(4字节或8字节)字段创建和维护索引所化的时间绝对比创建和维护32字节的字符字段的索引使用的时间要少。
  效率总是相对的,我并不是说UUID效率差,而是与整数相比效率稍差,这就好比windows和linux。都知道windows速度慢不稳定,但是使用windows的还是很多,那是因为它简单易用。
0 请登录后投票
   发表时间:2004-08-27  
对于是否使用业务主键(不知道是谁命名的,我看微软和IBM的网站上叫nature key,中文网站上叫自然键)的问题,微软和IBM的网站上都建议采用人工键。大家不要再讨论了,人家早都把它当作设计定式了。有什么好处,自己想想就知道了。
至于如何去生成这个键的问题,我的做法是采用一个实现singleton的类来产生这个主键。这个类有产生递增的int,也可以产生uuid。当然可以结合工厂模式来让它有不同的实现。不过,我没有搞得那么复杂,给每个表搞了一个。这样最简单。我的每个表的ID都是自动产生的。我一直这样做的,没有遇到什么问题。
0 请登录后投票
   发表时间:2004-08-27  
自己维护也可以,不过如果写成Singletone就要考虑分布式的问题了
赫赫,是不是脱离了轻量级的范畴,如果对ID增量要求不高,UUID的确很好
0 请登录后投票
   发表时间:2004-09-21  
我常用uuid,java生成的效率不低,就是在批量生成也不低,根本不能影响到性能。
有朋友说查询的命中率问题,我不了解这方面,我想有一定的道理,
uuid还有一个很好的好处可能大家都没注意到,就是数据库导入导出。以前用oracle的序列,老是导数据出错。还有就是多表数据整合到一个表中时。这样主键也不会冲突。
可能表中是海量级数据,可以用int形,但更多的时候我们的表中数据不会很多。所以我感觉看情况,
uuid生成的东西不会有同样的。这点不用怀疑,看看生成的原代码就明白了。
uuid的一个不好点就是看不懂意思。也也可以说是一个好处。
如新闻,传入ID显示,如果ID是整数,客户可以把整数加减或是乱输入一个整数就可以看到其它内容,但uuid就不行。
0 请登录后投票
   发表时间:2004-11-18  
跟着看了半天,很奇怪大家为什么不用sequence?用了那么多年了都没有任何问题。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics