为什么是UUID做主键


转自http://setting.iteye.com/blog/1064017

ING-专业要饭(xxx)  22:43:32
现在好多项目数据库的表ID都是用UUID哦,这是为什么?
ING-专业要饭(xxx)  22:43:37
ashier.htm?orderId=879b2c046adf664e40bd6b7b7e1f6d6f&
ING-专业要饭(xxx)  22:43:46
这是支付宝的。
境由心造(xxx)  22:46:59
安全?
kimmking(xxx)  22:47:16
最重要的原因是 全局唯一性

ING-专业要饭(xxx)  22:47:30
还有捏?
境由心造(xxx)  22:47:51
UUID 可以保证百亿次都是唯一的吗?
kimmking(xxx)  22:48:01
安全性 可移植性
ING-专业要饭(xxx)  22:48:13
还有捏?
境由心造(xxx)  22:49:29
事情开始是这样的,然后呢,没有然后了
john(xxx)  22:51:57
可以隐藏业务信息
ING-专业要饭(xxx)  22:52:25
我们公司那破项目所有主键ID合TMD用UUID,我当初感到奇怪,后来仔细想想,也只有这些原因啦。

john(xxx)  22:53:15
普通的项目没必要用uuid吧
kimmking(xxx)  22:54:07
identity、increment单表内绝不会重复
sequence全库内绝不会重复
境由心造(xxx)  22:54:13
哦 这无所谓了
kimmking(xxx)  22:54:38
但是UUID的优势是,在一般的数据量(所有目前已知的数据量)下。
kimmking(xxx)  22:54:52
整个时空内不会重复。
ING-专业要饭(xxx)  22:55:00
KK,我有个问题。
境由心造(xxx)  22:55:09
 时空?
kimmking(xxx)  22:55:15
比如,我把一批数据,分散到各个主机上。
ING-专业要饭(xxx)  22:55:17
当identity 的值达到最大值时,会出现什么情况?
kimmking(xxx)  22:55:51
每个主机上每插入一条数据,就需要一个id,怎么做呢?
kimmking(xxx)  22:56:11
他们都是物理意义上的对等关系。
kimmking(xxx)  22:56:48
A1机器、A2,、A3,,,上的每条记录都可能是支付宝的订单。
kimmking(xxx)  22:56:53
怎么办呢?
kimmking(xxx)  22:57:31
identity、increment不行,因为A1里有一个id=1,A2里就不能有了。
john(xxx)  22:57:38
看设置,oracle序列可以循环。超过最大值报错
kimmking(xxx)  22:58:42
sequence可以,但是很麻烦。可以设置一台机器S,专门用来分配sequence,A1,、A2、A3.。。等等写入记录的时候,都来找S要一个id。
kimmking(xxx)  22:59:08
这就是说,A123都需要知道S的存在。我们引入了一个单点。
kimmking(xxx)  22:59:29
S发送down机的话,A123都不能用了。
kimmking(xxx)  22:59:53
UUID因为它的全局唯一性,可以很简单的避免这个问题。
kimmking(xxx)  23:00:15
A123各个机器自己算个UUID就得了。
kimmking(xxx)  23:00:31就能保证各个机器上出来的id,都是不一样的了。

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

附:hibernate可以支持13种策略生成主键,包括increment,identity,sequence,uuid等.

下面是主要策略的比较:
identity:由底层数据库生成标识符identity是由数据库自己生成的,但这个主键必须设置为自增长,前提条件是低层数据库支持自动增长字段类型  

increment:由hibernate管理主键,自动以递增的方式生成标识符,每次增量为1其在每次插入前取得一个当前最大的id+1作为主键,该主键必须为Integer类型.主键按数值顺序递增此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键这种方式可能产生的问题是:不能在集群下使用 

uuid.hex  
由   Hibernate   基于128   位   UUID   算法   生成16   进制数值(编码后以长度32   的字符串表示)作为主键 
uuid.string  
与uuid.hex   类似,只是生成的主键未进行编码(长度16),不能应用在   PostgreSQL   数据库中

下面是hibernate的注解如何配置:

@GeneratedValue 默认情况下会采用auto生成方式

如果要采用uuid的生成方式,由于jpa注解不支持此种方法,则要用hibernate的注解联合起来使用
具体的用法如下:
@GenericGenerator(name="idGenerator", strategy="uuid") //这个是hibernate的注解
@GeneratedValue(generator="idGenerator") //使用uuid的生成策略

posted @ 2011-05-30 18:58 highriver 阅读(...) 评论(...) 编辑 收藏