网络和 StackOverflow 上有大量有关 GUID 的信息。关于独特性的问题确实层出不穷。这不是一个关于2^128唯一性的问题。
我的问题是确定.NET 中 GUID 的第一部分(具体来说是前四个字节)的随机性。根据研究,它被认为是时间戳的最低有效 32 位。但是时间戳是如何转换的呢?这到底有多随机?
有谁知道.NET 的第一部分是如何构建的以及是否真正均匀分布在 4 个字节中?
如何使用时间戳来构造前 32 位?
时钟精度如何影响它?
Microsoft 是否尝试过确保前 4 个字节是否趋于随机?
原因:大量 Guid 使用对于前 4 个字节中的良好随机 GUID 有 2 个主要业务案例。如果每个新 GUID 的分布均匀,则可以根据需要的分区数量使用基于前 1、2、3 或 4 个字节的表分区。我见过一个 20 亿行的表,每天有 1000 万次插入,有 128 个分区,使用前 2 个字节作为分区键。注意,在 DB2 下,必须使用密钥的第一部分。引用 DB2 DBA。这极大地提高了数据库的吞吐量。第二个用途是批处理作业并行密钥分配。如果您知道批处理任务大约有 N 行,则可以将键范围分配给并行作业。如果没有同质分割,调度程序必须首先计算每个作业的起始键和终止键。如果这意味着读取 1 亿个数据并在内存中管理它们只是为了调度工作,那么前 x 分钟就会因作业调度而丢失。在我看到的示例中,时间约为 15 分钟。因此,有 2 个充分的理由使用并希望均匀分布 GUId。
SAP Banking 系统实际上引入了自定义 GUID 例程来解决 GUID 第一部分中缺乏随机性的问题。对于那些有权访问 SAP 银行系统的人来说,函数是 BANK_DISTRIBUTED_ID_CREATE。代码中的注释解释了他们这样做的原因。对于那些有权访问 SAP 支持的人,有一条注释 496904 解释了为什么他们认为有必要修复指南。
在使用自定义例程之前,AIX 下的 GUID 存在明显的偏差。C++ 内核。是的,独特,但随机,尤其是第一部分,显然不是。
更新:我决定编写一个程序来调查:Windows XP、Dell Intel Core 2 Duo 上的.net 4。
如果您感兴趣,我已经提供了测试程序结果。使用生成的指南
var G = Guid.NewGuid();
Run Code Online (Sandbox Code Playgroud)
结果在 SAMPLE 100,000,000 guid 上看起来不错。(更大的集合仍在运行)就我的目的而言,看起来分布均匀,足以假设没问题。
Byte 0: with Value 6A was least frequent : 389140 times
Byte 0: with Value 58 was most frequent : 392241 times
Byte 1: with Value 25 was least frequent : 388905 times
Byte 1: with Value B3 was most frequent : 392552 times
Byte 2: with Value D2 was least frequent : 389114 times
Byte 2: with Value CC was most frequent : 391984 times
Byte 3: with Value 66 was least frequent : 388744 times
Byte 3: with Value 16 was most frequent : 392838 times
Run Code Online (Sandbox Code Playgroud)
编辑:根据评论添加背景研究
我见过 AIX 系统上的 GUID 示例。我们已经超过20亿了。它们分布不均匀。2 个字节中有明显的偏差。因此,引入了一个特殊的例程来生成同质指南。我想知道 .net 是否也有类似的偏差