web-dev-qa-db-ja.com

GUID衝突は可能ですか?

関連付けられているアプリを使用する各ユーザーに対してGUIDを使用するSQL Server 2000のデータベースで作業しています。どういうわけか、2人のユーザーが同じGUIDになりました。アルゴリズムを使用して、ランダムGUIDを生成します。これは、衝突を引き起こす可能性が非常に低いですが、衝突は可能ですか?

111
Jason Baker

基本的にはありません。誰かがあなたのデータベースをいじりに行ったと思います。バージョンに応じてGUID使用している値は一意(バージョン1 GUIDなど)または一意で予測不能(バージョン4 GUIDなど)のいずれかです。SQLServerの実装NEWID()関数は128ビットの乱数を使用しているように見えるため、衝突は発生しません。

衝突の可能性が1%の場合、約 2,600,000,000,000,000,0 GUIDを生成する必要があります。

122
Tom Ritter

基本的には不可能!、可能性は天文学的に低いです。

しかし...私は、私が知っている世界で唯一の人ですGUIDコリジョンワンス(うん!)。

そして、私はそれを確信しており、それが間違いではなかったことを確信しています。

Pocket PCで実行されていた小さなアプリケーションで、操作の最後に、生成されたGUIDが必要なコマンドが実行される必要があります。サーバーは、実行日とともにサーバー上のコマンドテーブルに格納されていました。デバッグのある日、モジュールコマンド(新しく生成されたGUID添付)を発行しましたが、何も起こりませんでした。 (同じGUIDを使用して、操作の開始時にGUIDが1回だけ生成されたため)もう一度やり直し、何もせずに、最後にコマンドが実行されない理由を見つけようとして、コマンドテーブルをチェックし、同じGUID 3週間前に現在のものが挿入されました。これを信じないで、2週間のバックアップからデータベースを復元しました。GUIDがありました。コードをチェックし、新しいGUID Pow guidの衝突は1回しか発生しませんでしたが、代わりに宝くじで勝ったことを願っています。

編集:この可能性を大幅に高める可能性のあるいくつかの要因があり、アプリケーションはPocketPCエミュレーターで実行されていました。エミュレーターには状態保存機能があります。つまり、状態が復元されるたびにローカル時刻も復元されますまた、GUIDは内部タイマーに基づいています。また、コンパクトフレームワーク用のGUID生成アルゴリズムは、たとえばCOMのものよりも完全ではない可能性があります。

103
Pop Catalin

理論的には可能ですが、3.4E38の可能性のある数値を使用すると、1年で数十兆のGUIDを作成した場合、1つの重複が発生する可能性は0.00000000006( Source )です。

2人のユーザーが同じGUIDで終わった場合、データのコピーまたは共有を引き起こしているバグがプログラムにあると思います。

29
Ben Hoffstein

最初に、2つのGUIDの衝突の可能性を見てみましょう。 誕生日パラドックス のため、他の回答が述べているように、2 ^ 128分の1(10 ^ 38)ではありません。つまり、50%の確率で2つのGUIDが衝突する確率は実際には1 2 ^ 64(10 ^ 19)でかなり小さくなります。ただし、これは依然として非常に大きな数であるため、妥当な数のGUIDを使用していると仮定した場合の衝突の可能性は低くなります。

また、多くの人が信じているように、GUIDにはタイムスタンプまたはMACアドレスが含まれていないことにも注意してください。これはv1 GUIDには当てはまりましたが、 現在はv4 GUIDが使用されています。これは単に擬似乱数です これは、時間とマシンに固有ではないため、衝突の可能性がほぼ高いことを意味します。

本質的に答えはイエスであり、衝突は可能です。しかし、彼らはほとんどありません。

編集:2 ^ 64と言うように修正

20
Greg Beech

2つのランダムなGUIDが衝突する可能性(10 ^ 38に1回)は、破損したTCP/IPパケットを検出しない可能性(10 ^ 10に1回)よりも低くなります。 http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf 、11ページ。これは、ディスクドライブ、CDドライブなどにも当てはまります。 ...

GUIDは統計的に一意であり、dbから読み取るデータは統計的に正しいだけです。

17
Tony Lee

Occamの剃刀 をこの場合の良いガイドと考えます。 GUID衝突が発生する可能性は非常に低いです。バグがあるか、誰かがデータを乱用している可能性が高いです。

12
Jason Jackson

ウィキペディアの Globally Unique Identifier の記事を参照してください。 GUIDを生成するにはいくつかの方法があります。どうやら、古い(?)方法はMacアドレス、非常に短いユニットまでのタイムスタンプ、および同じコンピューターで高速世代を管理するためのユニークなカウンターを使用していたため、それらを複製することはほとんど不可能です。しかし、これらのGUIDはユーザーの追跡に使用できるため、削除されました...

Microsoftが使用している新しいアルゴリズムについては確信がありません(この記事では、GUIDのシーケンスを予測することができ、タイムスタンプを使用しなくなったように見えますか?.

現在、GUIDは、名前によってグローバルに一意になるように慎重に設計されているため、不可能であるか、非常に低い確率で発生する可能性があります。私は他の場所を見ます。

11
PhiLho

重複したMACアドレスを持つイーサネットカードを備えた2台のWin95マシンは、厳密に制御された条件下で重複GUIDを発行します。特に、たとえば建物の電源が切れ、両方がまったく同時に起動した場合です。

9
Joshua

GUIDは魔法であり、一意であることが保証されているという気持ちの良い答えが好きな人を知っていますが、実際には、ほとんどのGUIDは121ビットの乱数にすぎません(7ビットは書式設定に無駄になります)。大きな乱数を使用することに不安を感じる場合は、GUIDを使用することに不安を感じるべきではありません。

5
Rick Yorgason

これは、「私はネットワーキングの人ではないので、以下のように完全に一貫性のない文章を作成する可能性があります。」と前書きします。

イリノイ州立大学で働いていたとき、私たちは2台のDellデスクトップを異なる時間に注文しました。最初の1つをネットワークに配置しましたが、2つ目をネットワークに配置しようとすると、クレイジーなエラーが発生し始めました。多くのトラブルシューティングを行った結果、両方のマシンが同じGUIDを生成していることがわかりました(正確には何のためかわかりませんが、ネットワーク上で両方とも使用できなくなりました)。不良品として。

3
John Kraft

GUIDにバグがあるかもしれませんか?はい、もちろん可能です。しかし、答えはコンパイラのバグの場合と同じです-あなた自身のコードは注文ですバグの可能性が高いので、最初にそこを見てください。

3
Mark Ransom

もちろん可能です。可能性は低いですが、可能です。

同じマシンがすべてのGUID(サーバー)を生成しているため、マシン固有の情報に基づいた「ランダム性」の多くは失われます。

2
FlySwat

笑顔のために、次のスクリプトを試してください...(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

これを繰り返し実行すると(1秒もかかりません)、非常に短い時間差があっても、最初の選択からかなり広い範囲が生成されます。これまでのところ、2番目の選択では何も生成されていません。

1
GalacticCowboy

ユーザーがネットワークカードを搭載した別のマシンを使用している場合は不可能であり、そうでない場合でも、非常にわずかな理論上のリスクです。

個人的には、GUID=クラッシュよりもバグである可能性が高いため、他の場所を探します。

もちろん、短くするためにGUIDからビットを切り落とさないことを提供します。

0

確かにそれは可能であり、おそらくそうです。各GUIDが可能な数字空間のランダムな部分にあるわけではありません。 2つのスレッドが1つのスレッドを同時に生成しようとした場合、何らかの集中型GUID関数とその周辺のセマフォがなければ、同じ値になる可能性があります。

0
Kirk Strauser

SQL ServerのNEWID()関数のようなものを使用して衝突を生成する場合、GUID衝突に遭遇する可能性は非常に低いです(もちろん、他の答えとしても可能です)彼らが指摘していないことの1つは、実際には、野生のブラウザーでJavaScriptでGUIDを生成している場合、衝突が発生する可能性が非常に高いということです。ブラウザ、ただし、Googleスパイダーがそのような関数の結果をキャッシュするように見える問題に遭遇し、同じGUIDをシステムに繰り返し渡すことになりました。

詳細については、さまざまな回答を参照してください。

JavaScriptでUUIDを生成する際の衝突?

0
Ken Smith