【发布时间】:2023-03-28 03:24:01
【问题描述】:
很多人说 ObjectId 包括:
- 一个 4 字节的值,表示自 Unix 纪元以来的秒数(直到 2106 年才会用完秒数)
- 一个 3 字节的机器标识符(通常来自 MAC 地址),
- 一个 2 字节的进程 ID,以及
- 一个 3 字节的计数器,从一个随机值开始。
如果 objectId 包含所有这些元素,则可以保证所有 id 在集群中都是唯一的。但是文档说没有机器和进程 ID,并且 objectId 只包含一个随机值 (https://docs.mongodb.com/manual/reference/method/ObjectId)
我查看了java mongo驱动ObjectId的生成,找到了证据:
SecureRandom secureRandom = new SecureRandom();
RANDOM_VALUE1 = secureRandom.nextInt(0x01000000);
RANDOM_VALUE2 = (short) secureRandom.nextInt(0x00008000);
// ...
private ObjectId(final int timestamp, final int counter, final boolean checkCounter) {
this(timestamp, RANDOM_VALUE1, RANDOM_VALUE2, counter, checkCounter);
}
因此,有可能(好吧,概率非常低,但仍然如此)两台机器生成相同的随机数,并且所有因此生成的 id 很可能会发生冲突。为什么会做出这样的决定?它仍然是完全独特的,但我不明白吗? 谢谢!
编辑:好吧,问题的目的是:我应该自己实现MAC地址和processId的检索并生成ObjectId还是留下随机的5个字节数,因为没有区别?
【问题讨论】:
-
我不确定这个问题的目的是什么,但只是为了争论,您可以争辩说原始版本也不能保证 100% 的唯一性。话虽如此,这两种解决方案都给出了一个唯一的(“足够”?)id。
-
@TomSlabbaert 为什么原始版本不保证这一点?计数器(最后 3 个字节)保证在一台机器上生成的所有 id 都是唯一的。而address+process 5字节保证2台机器上生成的objectIds总是会不一样,因为2台机器总是有不同的mac地址(或者进程id,如果它们在单台机器上运行的话)