2013-03-03 10 views
15

私は、データベースプライマリキー列に固有のLong IDを生成する必要があります。UUIDを使用して一意のLongを生成する方法

私は)私はUUID.randomUUIDを(使用できると思った。getMostSignificantBits()時にはそのは私にとって問題であるいくつかの負の長いもを生成します。

UUIDから正のlongだけを生成することは可能ですか?何十億というエントリのようになりますので、生成された各キーは一意でなければなりません。

+0

なぜシーケンスを使用しないのですか?あなたはそのようなものを使うことができますか?またはUUIDこれはあなたが使用しなければならない解決策ですか? –

+0

あなたは配列の詳細を説明できます –

+0

どのようなDBを使用していますか?どのようなデータベースフレームワーク(JDBC、Hibernate、myBatis)を使用していますか? – Taky

答えて

4

http://commons.apache.org/sandbox/commons-id//index.html あなたに必要なものを正確に与えることができるLongGeneratorがあります。また

あなたが休止状態を使用している場合、あなたは一例http://grepcode.com/file/repo1.maven.org/maven2/hibernate/hibernate/2.1.8/net/sf/hibernate/id/TableHiLoGenerator.java#TableHiLoGeneratorのための彼らの実装を見てみることができない場合には、あなたは、(それはあなたがから選ぶことができますいくつかのアルゴリズムを持っている)あなたのためのIDを生成するためにそれを頼むことができます)

+0

これも良く見えます。 –

+0

LongGeneratorは、衝突する可能性のあるシーケンシャルIDを作成します。 GUIDは普遍的なユニークですが。それはSaurabhの必要条件を満たすかもしれませんが、これは完全に正しい答えではないと私は考えます。 – Sap

+0

Apache commons-idはダウンロードできません。他の選択肢? – user12458

1

私はこの解決策を見つけました。私は解決策を理解しようとしている時間です。それは、Javaのtwitter snowflake実装です。 twitterスノーフレークID生成アルゴリズムに基づく64ビットシーケンシャルIDジェネレータ。

https://github.com/Predictor/javasnowflake

任意の提案を歓迎します。

+0

しかし、私は再びパブリック同期文字列generateLongId()を参照してください。同期化されたブロックは、長期的にパフォーマンスを低下させます。 –

+1

同期が原因で発生するパフォーマンスの低下は、長時間または短時間でどのように変化しますか? – user93353

+2

@SaurabhKumar小さな同期ブロックでパフォーマンスの問題に遭遇することは非常に疑問です。同期は一般的にCASよりも遅くはない(つまり、JavaのNIOでもgoogleはこれに関する素晴らしい話をしていました)、データベースのシリアルIDジェネレータよりもずっと高速です(IDの前提やデータベースの往復などが必要であると仮定します)。 Javaで同期化された膨大な量のものがあることも知っておくべきです(ほとんどのサーブレット・コンテナはどこかでそれを行います)。 –

3

他の人が書いたように、longには一意の番号のための十分なスペースがありません。しかし、多くの場合、数字は特定の用途のために十分にユニークである可能性があります。 たとえば、ナノ秒精度のタイムスタンプで十分な場合があります。 それは、20ビットがナノ秒のためのスペースを割り当てる左現在のミリ秒をシフトした後、ナノ秒でそれを重ねる取得する:

(System.currentTimeMillis() << 20) | (System.nanoTime() & ~9223372036854251520L); 

ナノ&〜9223372036854251520L部分は現在のナノ秒を受け取り、最初の44のバイトを設定します

nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000 

サイドノート:0に、1ミリ秒(999999またはnanos) までナノ秒を表すだけ右に20ビットを残してそれと同じであるナノ秒は、電流を表すために使用されるべきではありませんその出発点は時間内に固定されておらず、最大に達したときにリサイクルされるためです。

他のビット操作も使用できます。現在のスレッドID、プロセスID、IPなど、現在の時刻と他のものを考慮に入れておくとよいでしょう。

12
UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE 
+1

サードパーティのライブラリを使用しないので、私はこれが好きです:) – DoctorD

関連する問題