2016-03-26 12 views
1

複数のクライアントデータベース間でグローバルに一意である必要があるため、一部のデータをいくつかの時点でマージする必要があるため、一部のテーブルの主キーにUUIDを使用する必要があります。JavaシーケンシャルUUID

VARCHAR(36)列とjavaのバージョン4のUUIDランダムジェネレータを使用すると問題が解決しますが、UUIDが連続していないため、インデックスや挿入に関する別の問題が発生することがあります(1,000万行以上)

私は、UUIDからの最も重要なビットを現在のタイムスタンプ(これらのビットはすでにタイムスタンプを表しています)で置き換えることによって、順次でランダムなUUIDを生成しようとしています。私はこれを行うWeb上のソリューション、つまりCOMB UUIDがあることは知っていますが、不思議なことに、Java実装を見つけることができませんでした。私はこれが共通の問題だと思った。

私はここでのC#上で、興味深い実装が見つかりました:似たようなアプローチは、何が必要だろう http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database

が、私は、Javaにこれを変換する苦労を抱えているので、誰も私を助けることができれば、私は」それを感謝します。私はJavaがビッグエンディアンを常に使用し、ネイティブOSからのものではないと考えるように、ビッグエンディアン/リトルエンディアンに関する問題の大部分はと思いますか?これに対処する方法については本当にわかりません。

私の考えは基本的に同じですが、UUID.randomUUID()を使用してUUIDを生成し、その結果のIDからSystem.currentTimeMillis()を置き換えます。

time_low    = 4*<hexOctet> 
time_mid    = 2*<hexOctet> 
time_high_and_version = 2*<hexOctet> (1 byte for UUI algorithm version) 

:私たちは6バイトと現在のタイムスタンプを表現することができると思うと、まだUUIDのタイムスタンプ部分は7.5バイトを使用していますので、私はよく分からないことの一つは、私はこのために必要があると思いバイトの量についてです編集:これまでの回答に感謝しますが、私の質問は、Java上で上記のアルゴリズムを実装し、このための別の代替手段を見つけることではないことを理解してください。私はいくつかの可能性があることを理解しています。クライアント識別子を含めて言及されているものは、これまで私が使ってきたものですが、その解決策はあまり好きではなく、このプロジェクトには当てはまりません主に2つの理由があります: - これは、クライアントの量が分かっている場合にはうまくいく可能性があります。つまり、クライアントごとにランダムなIDを生成してできるだけユニークにする必要があります。クライアントIDのプレフィックスの文字列と、順次部分のかなりの数は、50 +文字のプライマリキーを意味するものではありません。 - これは私が解決しようとしている問題を解決しません。これは、シーケンシャルプライマリキーを持つことです。異なるクライアントから同じテーブルにレコードを挿入すると、インサートはもはや連続しなくなり、パフォーマンスが低下します。

+0

は、ご使用のアプリケーションサーバーを1つのプロセスまたは分散していますか? –

+0

UUIDは、索引構成表を使用する場合(つまり、クラスタ化索引がある場合)のみ、「問題」を発生させます。それを避けたい場合は、代わりにヒープ構成テーブルを使用してください。 –

+0

それは配布されています。データベースモデルを制御できず、プライマリキーインデックスがクラスタ化されています。 – mfc

答えて

0

UUIDを手作業で操作する場合、それらは一意になる可能性がありますが保証されません。行が多いほど、ヒット確率は高くなります。

より優れた設計は、クライアントコードとsequenceeオブジェクトを使用して増加する整数を持つマルチパート主キーを持つことです。

データベースが独立して動作し、データウェアハウスなどの集約時に一意性だけが必要な場合は、クライアントコードをウェアハウスの読み込みにのみ組み込みます。

データの設計が不変で、PKにUUIDを使用する必要があると言いますが、ランダム化するつもりがない場合は間違った設計です。

+0

UUIDであっても、彼らが一意になるという保証はありません。それは本当に間違った質問です。複製が生成される可能性は常にあります。ランダム化はまだ実行されていますが、今回は、タイムスタンプに基づいて生成された部分を別のものに置き換えます。衝突の可能性は増しているかもしれませんが、それでも起こる可能性は非常に低いですし、このアプリケーションの使用では完全に受け入れられるので、重複IDが生成されるよりも2回連続して宝くじに勝つ可能性が高くなります。 – mfc

+0

あなたのデータベースデザインは最初から妥協しているように見えますが、サイトとシーケンスに基づいて2部構成のPKに行き、一意性を保証してください –

+0

しかし、すべての挿入が私の主な質問であるとは保証できません。 – mfc

1

あなたはこれを考えすぎるかもしれません。

は、次の2つの要件(あなたのデータベース間)

  1. グローバルユニーク

    のIDを持っているようです。
  2. 各データベース内で順次生成されるID。

各データベースに一意の識別子を割り当て、順次生成された値を追加して識別子を取得することをお勧めします。 -1、A-2、-3、等

  • Bで識別子を生成する:

    • Aがこの順で識別子が生成されます。私は2つのデータベースAとBがある場合、例えば

      、この順序はB-1、B-2、B-3など

    識別子はグローバルに一意であり、順次です。

    実際にこの識別子は、DB識別子(AまたはBなど)とシーケンス番号(整数型として格納されたもの)の2つの列として実装されます。

    実際に2つのデータベース間で行をマージする必要があるときまで、DB識別子の作成を遅らせることさえできます。