Java 是否可以安全地使用System.currentTimeMillis()生成唯一的数据库ID?

Java 是否可以安全地使用System.currentTimeMillis()生成唯一的数据库ID?,java,time,uniqueidentifier,Java,Time,Uniqueidentifier,我在Java中使用System.currentTimeMillis()(它返回一个long整数)为数据库实体生成一个唯一的ID,因为我假设这些时间在任何时候都不可能重叠 这是一个安全的假设吗 例如,目前我得到以下信息: 1296691225227 这是不太可能发生冲突的,是的(除非您处于高负载系统中,在这种情况下很可能发生),但仍然有可能 Java有一种生成唯一标识符的现有机制,但是-Java.util.UUID。它有生成随机ID的方法 我强烈建议用它来代替。不,这不安全。毫秒是CPU周期中很

我在Java中使用
System.currentTimeMillis()
(它返回一个
long
整数)为数据库实体生成一个唯一的ID,因为我假设这些时间在任何时候都不可能重叠

这是一个安全的假设吗

例如,目前我得到以下信息:

1296691225227

这是不太可能发生冲突的,是的(除非您处于高负载系统中,在这种情况下很可能发生),但仍然有可能

Java有一种生成唯一标识符的现有机制,但是-
Java.util.UUID
。它有生成随机ID的方法


我强烈建议用它来代替。

不,这不安全。毫秒是CPU周期中很长的一段时间(它们以每秒数十亿个周期的速度运行,而不是数千个),因此如果一次有多个请求,或者如果多个线程都尝试创建数据库条目,它们将看到相同的CPU时间,并最终导致键冲突。如果系统时钟以某种方式重置或更改为较早的时间,您也会遇到问题。

如果您的代码曾经在集群环境中运行,则会增加发生id冲突的可能性

大多数JPA数据库都有自己生成唯一ID的方法


还值得注意的是,虽然毫秒计时器的最小粒度理论上为1ms,但实际粒度可能更大。我曾经使用过20ms的系统。更不用说ntp将时钟向后移动。最小粒度是什么?我怎样才能检查我的系统的值呢?就故障概率而言,我怀疑毫秒方法能否通过单元测试或系统负载测试。当然不应该。。。如果你做得很好,我非常喜欢UUID,但是它效率很低(理解这一点很难…),通常的存储方式是UUID.toString(),它有36字节长(通常映射到varchar(36)之类的东西)。DB索引应该保存在内存中-索引越大,需要的内存越多,索引速度也会变慢,等等。我建议使用一些高-低方案w/集群位和
long
id.@bestsss:你能澄清一下你提出的集群位方案吗?