データベースの主キー列に対して一意のロングIDを生成する必要があります。
私はID.randomUUID()。getMostSignificantBits()を使用できると思ったが、時々それが負の長さを生成することも私にとっては問題である。
UUIDから正のlongのみを生成することは可能ですか?数十億のエントリがあるので、生成された各キーは一意でなければなりません。
http://commons.Apache.org/sandbox/commons-id//index.html を見てください。必要なものを正確に提供できるLongGeneratorがあります。
さらに、Hibernateを使用している場合は、IDを生成するように要求できます(選択可能な複数のアルゴリズムがあります)。そうでない場合は、たとえば、実装を見ることができます http:// grepcode.com/file/repo1.maven.org/maven2/hibernate/hibernate/2.1.8/net/sf/hibernate/id/TableHiLoGenerator.Java#TableHiLoGenerator )
UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE
これが機能する理由は、ビット単位で&1を実行すると同じ桁をそのまま通過させ、ビット単位で&0を実行するとブロックして結果が0になるためです。
0111111111111111111111111111111111111111111111111111111111111111
これは0であり、その後に63 1が続きます(合計は64ビットで、Javaでは長いです)
したがって、この数値でビット単位で数値Xを取得すると、左端のビットがゼロに変わることを除いて、同じ数値Xが得られます。つまり、値ではなくその数値の符号のみを変更したことになります。
他の人が書いたように、longには一意の番号を入れるのに十分なスペースがありません。しかし、多くの場合、番号は特定の用途に対して十分に一意である場合があります。たとえば、多くの場合、ナノ秒の精度のタイムスタンプで十分です。それを取得するには、現在のミリ秒を20ビット左にシフトして、ナノ秒のスペースを割り当ててから、ナノ秒でオーバーレイします。
(System.currentTimeMillis() << 20) | (System.nanoTime() & ~9223372036854251520L);
nano&〜9223372036854251520L部分は現在のナノ秒を取り、最初の44バイトを0に設定し、ナノ秒を表す右20ビットのみを1ミリ秒(999999ナノ)まで残します。
nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000
補足事項:ナノ秒は、開始点が時間的に固定されておらず、最大値に達するとリサイクルされるため、現在の時刻を表すために使用しないでください。
他のビット操作を使用できます。通常、現在の時刻と、現在のスレッドID、プロセスID、IPなどのその他のものを考慮に入れることをお勧めします。
このソリューションに出会ったばかりです。私はしばらくの間、ソリューションを理解しようとしています。Java Twitterスノーフレークの実装。TwitterスノーフレークID生成アルゴリズムに基づく64ビットシーケンシャルIDジェネレーター。
https://github.com/Predictor/javasnowflake
どんな提案でも大歓迎です。