Long uuid = UUID.randomUUID().getMostSignificantBits()
を使用している場合、衝突が発生する可能性はどのくらいですか。最下位ビットが切り捨てられるため、衝突が発生する可能性がありますよね?
ドキュメント によると、静的メソッドUUID.randomUUID()
はタイプ4 UUIDを生成します。
つまり、一部のタイプ情報には6ビットが使用され、残りの122ビットはランダムに割り当てられます。
6つの非ランダムビットは、UUIDの最上位半分に4つ、最下位半分に2つが分散されています。そのため、UUIDの最上位半分には60ビットのランダム性が含まれています。つまり、衝突を取得するには、平均で2 ^ 30 UUIDを生成する必要があります(フルUUIDの場合は2 ^ 61に比べます)。
ですから、あなたはかなり安全だと思います。ただし、Carl Seleborgが述べているように、これは他のタイプのUUIDには絶対に当てはまらないことに注意してください。
ちなみに、UUIDの最下位の半分を使用する(またはSecureRandomを使用してランダムなlongを生成する)ことで、わずかに改善されます。
レイモンド・チェンは、これに関する本当に素晴らしいブログ投稿をしています:
これがrandomUUIDを使用する最良の例だと思います:
ランダムな長い値を生成するだけで、すべてのビットがランダムになります。 Java 6では、新しいRandom()はSystem.nanoTime()とカウンターをシードとして使用します。
一意性にはさまざまなレベルがあります。
多くのマシンで一意性が必要な場合は、一意のID、または一意のIDのバッチを割り当てるための中央データベーステーブルを持つことができます。
1つのアプリで一意性が必要な場合は、カウンター(または要件に応じてcurrentTimeMillis()* 1000またはnanoTime()から開始するカウンター)のみを使用できます。
プレフィックスとしてTime YYYYDDDD
(年+年の日)を使用します。これにより、テーブルとインデックスのデータベースの断片化が減少します。このメソッドはbyte[40]
を返します。 Active Directory SID(varbinary(85)
)がLDAPユーザーのキーであり、アプリケーション自動生成IDが非LDAPユーザーに使用されるハイブリッド環境で使用しました。また、トランザクションテーブル(銀行業界)の1日あたりの大量のトランザクションでは、キーに標準のInt
タイプを使用できません
private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");
public static byte[] getSidWithCalendar() {
Calendar cal = Calendar.getInstance();
String val = String.valueOf(cal.get(Calendar.YEAR));
val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
val += UUID.randomUUID().toString().replaceAll("-", "");
return val.getBytes();
}