我正在使用SQL Server 2000中的一个数据库,该数据库为每个使用它所绑定的应用程序的用户使用GUID。不知何故,两个用户最终得到了相同的GUID。我知道微软使用一种算法来生成一个随机GUID,这个GUID极有可能造成冲突,但仍然可能发生碰撞吗?

有帮助吗?

解决方案

基本上没有。我觉得有人跟你的数据库混在一起。根据您使用的版本GUID,值是唯一的(对于版本1 GUID之类的东西),或者是唯一的和不可预测的(对于版本4 GUID之类的东西)。 SQL Server的NEWID()函数实现似乎使用了128位随机数,因此您不会发生冲突。

对于1%的碰撞机会,您需要生成 2,600,000,000,000,000,000 个GUID。

其他提示

基本上他们是不可能的!,机会天文数字低

但是......我是世界上唯一一个我所知道的人,曾经有一个GUID colision (是的!)。

我很确定,而且这不是一个错误。

如何实现,在Pocket PC上运行的小型应用程序中,在操作结束时,必须发出具有生成的GUID的命令。在服务器上执行该命令后,该命令与执行日期一起存储在服务器上的命令表中。有一天,当我调试时,我发出了模块命令(附加了新生成的GUID),没有任何反应。我再次做了(使用相同的guid,因为guid仅在操作开始时生成一次),并且再次没有,最后试图找出命令未执行的原因,我检查了命令表,和3周前插入的当前GUID相同。不相信这一点,我从2周的备份中恢复了数据库,并且guid就在那里。检查代码,新的guid新生成毫无疑问。 Pow guid碰撞,只发生过一次,但我真的希望我能在乐透中获胜,机会更大:)。

编辑:有一些因素可能会大大增加发生这种情况的机会,应用程序在PocketPC模拟器上运行,并且模拟器具有保存状态功能,这意味着每次状态恢复时本地时间也恢复了guid是基于内部计时器....紧凑框架的guid生成算法可能不如例如COM一个...

它们在理论上是可行的,但是对于3.4E38可能的数字,如果你在一年内创造了数万亿的GUID,那么一个副本的可能性是0.00000000006( Source )。

如果两个用户最终使用相同的GUID,我会打赌程序中存在导致数据被复制或共享的错误。

首先让我们看看两个GUID发生冲突的可能性。正如其他答案所说的那样,由于生日悖论,它不是1 ^ 2 128(10 ^ 38) ,这意味着两个GUID碰撞概率为50%的概率实际上是2 ^ 64(10 ^ 19)中的1,这要小得多。但是,这仍然是一个非常大的数字,因此假设您使用合理数量的GUID的冲突概率很低。

另请注意,GUID不包含时间戳或MAC地址,因为许多人似乎也相信。这对于v1 GUID是正确的,但是现在使用了v4 GUID,这只是一个伪随机数这意味着碰撞的可能性可以说更高,因为它们不再是时间和机器所独有的。

所以基本上答案是肯定的,碰撞是可能的。但他们极不可能。

编辑:固定为2 ^ 64

两个随机GUID冲突的机会(10 ^ 38中的〜1)低于未检测到损坏的TCP / IP数据包的机会(10 ^ 10中的〜1)。 http://www.inf.tu-dresden .de / data / courses / SE1 / SE1-2004-lec12.pdf ,第11页。磁盘驱动器,CD驱动器等也是如此......

GUID在统计上是唯一的,您从数据库中读取的数据仅在统计上是正确的。

在这种情况下,我会考虑奥卡姆剃刀作为一个很好的指南。你发生GUID冲突的可能性极小。你很可能有一个错误,或者有人弄乱你的数据。

请参阅维基百科的全球唯一标识符文章。有几种方法可以生成GUID。显然旧的(?)方式使用Mac地址,时间戳到一个非常短的单位和一个独特的计数器(在同一台计算机上管理快速生成),所以使它们复制几乎是不可能的。但是这些GUID被删除了,因为它们可以用来追踪用户......

我不确定微软使用的新算法(文章说可以预测一系列GUID,看起来他们不再使用时间戳了?上面链接的微软文章说了别的......)。

现在,GUID经过精心设计,按名称,全球独一无二,因此我将冒险这是不可能的,或者非常非常低的概率。我会去其他地方看看。

两台具有重复MAC地址的以太网卡的Win95机器将在严格控制的情况下发出重复的GUID,特别是例如,如果建筑物中的电源断电并且它们都在同一时间启动。

我知道人们喜欢感觉良好的答案,GUID是神奇的并且保证是唯一的,但实际上,大多数GUID只是121位随机数(格式化时浪费了7位)。如果您觉得使用大型随机数感觉不舒服,那么使用GUID会感觉不舒服。

用于生成GUID的代码是否有错误?是的,当然可以。但答案与编译器错误的答案相同 - 你自己的代码更有可能是错误的数量级,所以请先查看。

当然可能......可能吗?不太可能,但有可能。

请记住,同一台机器正在生成每个GUID(服务器),因此很多“随机性”基于机器特定信息的丢失。

只是为了咧嘴笑,请尝试以下脚本...(适用于SQL 2005,不确定2000)

declare @table table
(
    column1 uniqueidentifier default (newid()),
    column2 int,
    column3 datetime default (getdate())
)

declare @counter int

set @counter = 1

while @counter <= 10000
begin
    insert into @table (column2) values (@counter)
    set @counter = @counter + 1
end

select * from @table

select * from @table t1 join @table t2 on t1.column1 = t2.column1 and t1.column2 != t2.column2

重复运行(花费不到一秒),从第一次选择开始产生相当宽的范围,即使是非常短的时间间隔。到目前为止,第二个选择还没有产生任何东西。

如果用户使用不同的带有网卡的机器,则不可能,即使不是,它仍然是一个极其微小的理论风险。

就个人而言,我会在其他地方寻找,因为它更可能是一个错误,而不是GUID冲突......

当然,您不要将GUID中的位切掉,以缩短它。

当然有可能,甚至可能。这并不是每个GUID都在可能的数字空间的随机部分。如果两个线程试图同时生成一个线程,除了某种带有信号量的集中式GUID函数,它们最终可能会有相同的值。

我将在前面加上“我不是一个网络人,所以我可能会在后面做完全不连贯的句子。”

当我在伊利诺伊州立大学工作时,我们有两个戴尔台式机,在不同时间订购。我们把第一个放在网络上,但当我们试图将第二个放在网络上时,我们开始收到疯狂的错误。经过多次故障排除后,确定两台机器都生成相同的GUID(我不确定究竟是什么用,但它使它们在网络上都无法使用)。戴尔实际上将这两台机器更换为有缺陷的。

如果您通过SQL Server中的 NEWID()函数生成它们,那么您很可能会遇到GUID冲突(尽管当然可能,正如其他答案所强调的那样) 。他们没有指出的一件事是,如果你在野外的浏览器中使用JavaScript生成GUID,那么你很可能会遇到冲突。不仅在不同的浏览器中RNG有时会出现问题,但我也遇到了一些问题,谷歌蜘蛛似乎会缓存这类功能的结果,并最终反复将相同的GUID传递给我们的系统。

有关详细信息,请参阅此处的各种答案:

在JavaScript中生成UUID时发生冲突?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top