在.NET中创建的Guid的前四个字节是如何均匀分布的?

时间:2012-10-30 23:35:56

标签: .net guid

关于网络和StackOverflow上的GUID有很多信息。确实是关于独特性的无尽问题。这不是关于2 ^ 128唯一性的问题

我的问题是确定第一部分的随机性,确切地说,GUID的第一个四个字节在.NET中。基于研究,它被认为是最不重要的32位时间戳。但时间戳是如何转换的?这有多随机?

有人知道第一部分是如何由.NET构建的,并且是否真的均匀分布在4个字节中?

如何时间戳用于构建前32位

时钟精度如何影响它?

Microsoft是否试图确保前4个字节是随机的?

为什么:高容量Guid使用在前4个字节中有2个主要业务案例,用于良好的随机guid。如果每个新GUID都有均匀分布,则可以根据所需的分区数使用基于前1,2,3或4个字节的表分区。我看到一个20亿行表,每天有1000万次插入,128个分区使用前2个字节作为分区键。注意在DB2下,必须使用密钥的第一部分。引用DB2 DBA。这大大提高了数据库的吞吐量。第二种用途是批量作业并行密钥分配。如果您知道大约有N行作为批处理任务,则可以将键范围分配给并行作业。如果没有同质拆分,调度员必须首先计算每个作业的from和to键。如果这意味着读取1亿并在内存中管理它们只是为了分派工作,那么工作调度就会丢失前x分钟。在这个例子中,我看到它大概是15分钟。所以有两个很好的理由可以使用并且想要均匀传播GUI。

SAP Banking系统实际上引入了一个自定义GUID例程来解决GUID第一部分中缺乏随机性的问题。对于有权访问SAP银行系统的用户,函数为BANK_DISTRIBUTED_ID_CREATE。代码中的注释解释了他们为什么这么做。有权访问SAP支持的人有一个说明496904解释了为什么他们认为有必要修复guid。

在自定义例程之前,AIX下的GUID存在明显的偏差。 C ++内核。 独特的是,但随机,特别是第一部分,显然不是。

更新:我决定写一个程序来调查: Windows XP上的.net 4,戴尔Intel Core 2 Duo。

如果感兴趣的话,我已经包含了测试计划结果。 使用

生成Guid
var G = Guid.NewGuid();

SAMPLE 100,000,000 guids的结果看起来不错。(更大的设置仍在运行) 就我的目的而言,这看起来已经足够均匀,可以假设好了。

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

编辑:根据评论添加后台研究

我在AIX系统上看到过GUID样本。我们已经超过20亿。它们不均匀分布。 2个字节有明显的偏差。结果,引入了一个特殊的程序来产生同质的guid。我想知道.net是否有类似的倾斜

1 个答案:

答案 0 :(得分:0)

Guids似乎均匀分布。对10亿Guids的测试看起来不错。如果考虑前4个字节。这意味着它们对分区和范围有用,可以粗略推导出而不是从Db中读取。