C# 在查找数据的唯一ID时,依赖System.Guid.NewGuid()函数是否有任何缺点?

C# 在查找数据的唯一ID时,依赖System.Guid.NewGuid()函数是否有任何缺点?,c#,asp.net-4.0,C#,Asp.net 4.0,我希望生成唯一的ID来识别系统中的一些数据。我使用的是一个复杂的系统,它将一些(非唯一的、相关的)元数据与system.Guid.NewGuid()连接起来。这种方法是否有任何缺点,或者我是否清楚?当您使用System.Guid.NewGuid()时,您可能仍然需要检查Guid是否已经存在于您的系统中 虽然guid是如此复杂以至于实际上是唯一的,但除了概率之外,没有什么可以保证它不存在。这在统计学上是难以置信的不可能的,以至于在几乎任何情况下,它都是独一无二的 生成相同的guid就像中了两次彩票

我希望生成唯一的ID来识别系统中的一些数据。我使用的是一个复杂的系统,它将一些(非唯一的、相关的)元数据与system.Guid.NewGuid()连接起来。这种方法是否有任何缺点,或者我是否清楚?

当您使用
System.Guid.NewGuid()
时,您可能仍然需要检查Guid是否已经存在于您的系统中

虽然guid是如此复杂以至于实际上是唯一的,但除了概率之外,没有什么可以保证它不存在。这在统计学上是难以置信的不可能的,以至于在几乎任何情况下,它都是独一无二的

生成相同的guid就像中了两次彩票——实际上没有什么可以阻止它,它只是不太可能,也可能是不可能的

大多数情况下,您可能不会检查现有的匹配项,但在非常极端的情况下,如果有大量的生成,或者系统绝对不能失败,则值得检查

编辑


让我再澄清一点。您极不可能看到重复的guid。这就是重点。它是“全球唯一的”,这意味着复制的可能性非常小,你可以假设它是唯一的。然而,如果我们谈论的是使飞机在空中飞行、监视核反应堆或在国际空间站上处理生命维持的代码,我个人仍然会检查是否有重复的代码,只是因为击中边缘情况确实很可怕。另一方面,如果你只是在写一个博客引擎,那就继续吧,不用检查就可以使用它

请随意使用
NewGuid()
。它的独特性没有问题

它两次生成相同guid的概率太低;这里可以找到一个很好的例子:

var bigHeapOGuids=new Dictionary();
尝试
{
做
{
Guid=Guid.NewGuid();
添加(guid,guid);
}虽然(正确);
}
捕获(OutOfMemoryException)
{
}
在某种程度上,它只是在
OutOfMemory
上崩溃,而不是在重复的密钥冲突上崩溃

我希望生成唯一的ID来识别系统中的一些数据

我建议使用GUID,因为根据定义,它们是全局唯一的标识符

我使用的是一个复杂的系统,它将一些(非唯一的、相关的)元数据与system.Guid.NewGuid()连接起来。这种方法有什么缺点吗?或者我清楚了吗

好吧,因为我们不知道你会考虑什么缺点,这很难说。我想到了一些可能的缺点:

  • guid很大:128位是很多位

  • guid不保证有任何特定的发行版;按顺序生成guid是完全合法的,在124位空间上均匀分布guid也是完全合法的(128位减去版本号的四位)如果GUID被用作按GUID排序的数据库上的主键,则这可能会对数据库性能产生严重影响;如果新行始终位于末尾,则插入的效率会更高。一个均匀分布的GUID几乎永远不会结束

  • 版本4的guid不一定是随机加密的;如果guid是由非加密随机生成器生成的,那么攻击者在理论上可以预测您的guid是什么,只要给出一个具有代表性的样本。理论上,攻击者可以确定在同一会话中生成两个guid的概率。版本一的guid当然几乎是随机的,并且可以告诉复杂的读者它们是在何时何地生成的

  • 等等

在接下来的几周里,我计划写一系列关于guid的这些特性和其他特性的文章;查看我的博客了解详细信息


更新:

这是一个糟糕的例子。
HashSet
不会在添加重复元素时引发异常,只是不会添加它。这就是为什么它返回一个布尔值,指示是否添加了任何内容。@hvd:corrected asnwer。放入
词典
,然后重新测试。结果是一样的:没有键冲突,但内存异常。谢谢基于此,我认为有122位的可用空间:他说的是相同的实现吗?注意:虽然版本4的Guid不必是加密随机的,但它们的Windows实现是(当您使用Guid.NewGuid或CoCreateGuid时)。见第10节和第11节:@anank:很高兴知道,谢谢;我将更新文本。
var bigHeapOGuids = new Dictionary<Guid, Guid>();
try
{
   do
   {
      Guid guid = Guid.NewGuid();
      bigHeapOGuids.Add(guid ,guid );
   } while (true);
}
catch (OutOfMemoryException)
{
}