我想生成类似于Java中的自动递增的唯一ID。之前我使用了当前纳秒数,但由于两个数据在同一纳秒内到达,导致冲突。UUID能解决上述问题吗?
注意:在我的项目中,每分钟甚至可以获得10000行记录,我将把这些记录和UID存储到表中。可能会出现一种情况,即我停止产品并在一段时间后重新启动它...那么在这种情况下,UUID类如何将以前生成的UID(我存储在数据库中)与即将创建的新UID(尚未转储到数据库中)进行区分?
虽然UUID并不能保证唯一性,但是出现重复的概率极低。请参考随机UUID重复概率。
对于您的应用程序来说,使用UUID是有意义的,但是为了防范极其罕见的情况,您可能需要处理重复问题。
我严重怀疑你能在调用System.nanoTime()时获得两个记录的时间在同一纳秒内,因为System.nanoTime()的调用需要超过100ns。更可能的情况是您的时钟没有纳秒精度。
然而,如果你重新启动你的服务器,你可以得到重复的nanoTime()。
解决这个问题的一种方法是使用
AtomicLong counter = new AtomicLong(System.currentTimeMillis()*1000);
long id = counter.incrementAndGet();
// something like ctz9yamgu8
String id = Long.toString(counter.incrementAndGet(), 36);
应用程序重新启动时,这将启动一个计数器,并且在重新启动之间不会重叠,除非您每秒维持超过一百万个ID(在实例的生命周期内)。
注意:这仅适用于每个实例。多个服务器需要使用不同的方法。
这个页面似乎对UUID的性质存在一些混淆。
请阅读Wikipedia页面,您将会看到有不同的UUID版本。
您问道:
UUID是否解决了上述问题?
是的,UUID值确实解决了您的问题。
最初的版本1表示时空中的一个点,永远不会重复。
版本1通过使用生成它的计算机(空间中的一个点)的MAC地址,结合当前时刻和在注意到计算机时钟变化时递增的任意数字来实现。由于计算机现在具有内置电池和网络连接到时间服务器,所以时钟不再是一个问题。通过组合这些元素,几乎不可能发生碰撞。
由于跟踪和披露MAC地址和时刻可能涉及安全和隐私问题,一些人可能不想使用此版本。例如,Java从其UUID
类中省略了生成版本1。
值得一提的是,像Postgres这样更强大的数据库服务器可以生成包括版本1在内的UUID值。您可以选择在数据库服务器上生成UUID,而不是在应用程序中生成。
常用的版本之一是 版本4,其中的128位中有122位是随机生成的。如果使用密码学强度随机生成器,这是相当有效的。该版本与版本1相比具有更高的碰撞概率。但对于大多数实际情况来说,基于随机数的UUID是完全可靠的。