我正在寻找生成唯一 ID 来识别我系统中的一些数据。我正在使用一个精心设计的系统,它将一些(非唯一的、相关的)元数据与 System.Guid.NewGuid()s 连接起来。这种方法有什么缺点吗,还是我很清楚?
3 回答
我正在寻找生成唯一 ID 来识别我系统中的一些数据。
我会推荐一个 GUID,因为它们根据定义是global unique identifiers。
我正在使用一个精心设计的系统,它将一些(非唯一的、相关的)元数据与 System.Guid.NewGuid() 连接起来。这种方法有什么缺点吗,还是我很清楚?
好吧,因为我们不知道你会认为什么是缺点,所以很难说。我想到了一些可能的缺点:
GUID 很大:128 位是很多位。
不保证 GUID 具有任何特定的分布;按顺序生成 GUID 是完全合法的,在它们的 124 位空间(当然是 128 位减去作为版本号的 4 位)上均匀分布是完全合法的。这会对数据库产生严重影响如果 GUID 被用作数据库上的主键,该数据库按 GUID 的排序顺序进行索引,则性能;如果新行总是在最后,插入会更有效率。一个均匀分布的 GUID 几乎永远不会结束。
第 4 版 GUID不一定是加密随机的;如果 GUID 是由非加密随机生成器生成的,则攻击者理论上可以在给出具有代表性的样本时预测您的 GUID 是什么。理论上,攻击者可以确定在同一会话中生成两个 GUID 的概率。第一版 GUID 当然几乎不是随机的,并且可以告诉老练的读者它们是在何时何地生成的。
等等。
我计划在接下来的几周内撰写一系列关于 GUID 的这些和其他特征的文章;看我的博客了解详情。
使用 时System.Guid.NewGuid()
,您可能仍想检查系统中是否存在该 guid。
虽然 guid 如此复杂以至于几乎是唯一的,但除了概率之外,没有什么可以保证它不存在。这在统计上是难以置信的,以至于几乎在任何情况下它都与独特性相同。
生成相同的 guid 就像中了两次彩票 - 没有什么可以真正阻止它,它太不可能了,它也可能是不可能的。
在大多数情况下,您可能不检查现有匹配项而侥幸逃脱,但在非常极端的情况下,有大量生成,或者系统绝对不能失败,这可能值得检查。
编辑
让我再澄清一点。您极不可能看到重复的 guid。这才是重点。它是“全球唯一的”,这意味着重复的可能性非常小,您可以假设它是唯一的。但是,如果我们谈论的是让飞机在空中飞行、监控核反应堆或在国际空间站处理生命支持的代码,我个人仍然会检查是否有重复,只是因为它真的很糟糕击中那个边缘案例。另一方面,如果您只是在编写博客引擎,请继续使用它而无需检查。
随意使用NewGuid()
。它的独特性没有问题。
两次生成同一个guid的概率太低;一个很好的例子可以在这里找到:简单证明 GUID 不是唯一的
var bigHeapOGuids = new Dictionary<Guid, Guid>();
try
{
do
{
Guid guid = Guid.NewGuid();
bigHeapOGuids.Add(guid ,guid );
} while (true);
}
catch (OutOfMemoryException)
{
}
在某些时候,它只是崩溃了,OutOfMemory
而不是重复的密钥冲突。