好的,我自己在设计和制作上终于走到了这一步。
我生成了一个 COMB_GUID,其中高 32 位基于 Unix 时间的第 33 位到第 1 位,以毫秒为单位。因此,每 2 毫秒有 93 位随机性,高位的翻转每 106 年发生一次。COMB_GUID(或类型 4 UUID)的实际物理表示是 128 位的 base64 编码版本,即 22 个字符的字符串。
在 postgres 中插入时,完全随机的 UUID 和 COMB _GUID 之间的速度比对 COMB_GUID 有利。COMB_GUID在我的硬件上经过多次测试快2倍,用于一百万条记录测试。记录包含 id(22 个字符)、一个字符串字段(110 个字符)、一个双精度和一个 INT。
在 ElasticSearch 中,两者在索引方面没有明显区别。我仍将使用 COMB_GUIDS 以防内容进入链中任何位置的 BTREE 索引,因为内容与时间相关,或者可以在 id 字段上进行预排序,使其与时间相关且部分顺序,它将加快速度。
非常有趣。制作 COMB_GUID 的 Java 代码如下。
import java.util.Arrays;
import java.util.UUID;
import java.util.Base64; //Only avail in Java 8+
import java.util.Date;
import java.nio.ByteBuffer;
private ByteBuffer babuffer = ByteBuffer.allocate( (Long.SIZE/8)*2 );
private Base64.Encoder encoder = Base64.getUrlEncoder();
public String createId() {
UUID uuid = java.util.UUID.randomUUID();
return uuid2base64( uuid );
}
public String uuid2base64(UUID uuid){
Date date= new Date();
int intFor32bits;
synchronized(this){
babuffer.putLong(0,uuid.getLeastSignificantBits() );
babuffer.putLong(8,uuid.getMostSignificantBits() );
long time=date.getTime();
time=time >> 1; // makes it every 2 milliseconds
intFor32bits = (int) time; // rolls over every 106 yers + 1 month from epoch
babuffer.putInt( 0, intFor32bits);
}
//does this cause a memory leak?
return encoder.encodeToString( babuffer.array() );
}
}