GUID的哪一部分最值得保留?

我需要生成一个唯一的ID并且正在考虑使用Guid.NewGuid执行此操作,这会生成以下forms:

 0fe66778-c4a8-4f93-9bda-366224df6f11 

这对于它最终会驻留的字符串类型数据库列来说有点长,所以我打算截断它。

问题是:就唯一性而言,GUID的一端是否优于其他GUID? 我应该从开始,结束或从中间移除零件吗? 或者它没关系?

您可以使用base64字符串来节省空间:

 var g = Guid.NewGuid(); var s = Convert.ToBase64String(g.ToByteArray()); Console.WriteLine(g); Console.WriteLine(s); 

这将为您节省12个字符(如果您不使用连字符,则为8个字符)。

保留所有这些。

从以上链接:

 * Four bits to encode the computer number, * 56 bits for the timestamp, and * four bits as a uniquifier. 

你可以重新定义Guid以适合你的需要。

如果GUID只是一个随机数,您可以保留这些位的任意子集,并且可以使用“ 生日算法 ”计算一定百分比的碰撞几率:

 double numBirthdays = 365; // set to eg 18446744073709551616d for 64 bits double numPeople = 23; // set to the maximum number of GUIDs you intend to store double probability = 1; // that all birthdays are different for (int x = 1; x < numPeople; x++) probability *= (double)(numBirthdays - x) / numBirthdays; Console.WriteLine("Probability that two people have the same birthday:"); Console.WriteLine((1 - probability).ToString()); 

然而,碰撞的概率通常更高,因为事实上,GUID通常不是随机的。 根据维基百科的GUID文章 ,有五种类型的GUID。 第13位指定您拥有哪种GUID,因此它往往不会有太大变化,并且第17位的前两位始终固定为01

对于每种类型的GUID,您将获得不同程度的随机性。 版本4(第13位= 4)完全随机,除了数字13和17; 版本3和5实际上是随机的,因为它们是加密哈希; 虽然版本1和版本2通常不是随机的,但在实际情况下某些部分是相当随机的。 版本1和2 GUID的“问题”是许多GUID可能来自同一台机器,在这种情况下会有大量相同的位(特别是最后48位,许多时间位将相同) 。 或者,如果在不同的计算机上同时创建了许多GUID,则可能会在时间位之间发生冲突。 所以,祝你好运安全地截断它。

我的情况是我的软件只支持64位唯一ID,因此我无法直接使用GUID。 幸运的是,所有的GUID都是类型4,所以我可以得到64位随机或几乎随机的位。 我有两百万条记录要存储,生日算法表明碰撞的概率是64位的1.08420141198273 x 10 ^ -07和48位的0.007(0.7%)。 应该假设这是最好的情况,因为随机性的降低通常会增加碰撞的概率。

我认为理论上,未来可能存在比现在定义的GUID类型更多的GUID类型,因此不可能实现面向未来的截断算法。

截断GUID是个坏主意,请参阅此文章了解原因。

你应该考虑生成一个更短的GUID, 因为谷歌揭示了一些解决方案 。 这些解决方案似乎涉及获取GUID并将其更改为以完整的255位ascii表示。

我同意罗布 – 保留所有这些

但是既然你说你要进入数据库,我想我会指出只使用Guid并不一定意味着它会在数据库中很好地编入索引。 出于这个原因,NHibernate开发人员创建了一个更加DB友好的Guid.Comb算法。

有关详细信息,请参阅显示的NHibernate POID生成器和Guid算法文档。

注意: Guid.Comb旨在提高MsSQL的性能