目前我正在尝试在客户端生成long类型的唯一标识符。 我有父/子关系,父母已经有一个UUID作为标识符。 我想考虑Parent-UUID来计算long类型的Child-Id。
我现在有这个实现:
public static void main(String[] args) {
/** Funnel. */
final Funnel<UUID> UUID_FUNNEL = new Funnel<UUID>() {
@Override
public void funnel(UUID parentUUID, PrimitiveSink into) {
final UUID tmpId = UUID.randomUUID();
into
// consider parent uuid
.putLong(parentUUID.getMostSignificantBits())
.putLong(parentUUID.getLeastSignificantBits())
// consider tmp uuid
.putLong(tmpId.getMostSignificantBits())
.putLong(tmpId.getLeastSignificantBits());
}
};
final UUID parentUUID = UUID.randomUUID();
System.out.println(parentUUID.toString());
for (int i = 0; i < 1000; i++) {
final long childId = Hashing.murmur3_128().newHasher()
.putObject(parentUUID, UUID_FUNNEL)
.hash().asLong();
System.out.println(childId);
}
}
您如何看待这个想法? 欢迎任何建议。
我已经读过这个问题: How to generate unique Long using UUID
答案 0 :(得分:3)
这不会真的奏效。当然不比随机long
好。
tmpId
:您只对parentUUID
进行哈希处理,因此同一父级的所有子项都会获得相同的long
。tmpId
:您可以使用UUID.randomUUID().getLeastSignificantBits()
或仅使用random.nextLong()
并自行保存所有工作(无论您添加什么,哈希随机值都会导致随机结果)。< / LI>
我有多个客户,而不仅仅是一个。
然后问一个独特的服务器。这包括一些开销,可以使用hi-lo algorithm轻松最小化。
在数据库级别,子ID必须是唯一的。
然后忘记它并让DB生成id。每个数据库都有一些AUTOINCREMENT或SEQUENCE意味着这一点。
如果您在访问数据库之前需要客户端中的id,请询问数据库(并使用hi-lo算法以最小化开销)。
我刚刚看到你的评论:
客户端不应该去服务器获取下一个ID。必须可以脱机工作。
这是一个很大的痛苦。您可以做的任何哈希都不会比随机long
好。
long
的碰撞几率约为1e-6
,这可能是可以接受的。请注意,由于生日悖论,机会会随着设定的大小增加二次。UUID
。由于它们长度为128位,即使数十亿个ID,碰撞几率也几乎为零。