1

現時点では、クライアント側で long 型の一意の識別子を生成しようとしています。親が既に識別子として UUID を持っている親子関係があります。long 型の Child-Id を計算するための Parent-UUID を検討したいと思います。

私は現時点でこの実装を持っています:

public static void main(String[] args) {

    /** Funnel. */
    final Funnel<UUID> UUID_FUNNEL = new Funnel<UUID>() {
        @Override
        public void funnel(UUID parentUUID, PrimitiveSink into) {
            final UUID tmpId = UUID.randomUUID();
            into
             // consider parent uuid
            .putLong(parentUUID.getMostSignificantBits())
            .putLong(parentUUID.getLeastSignificantBits())
             // consider tmp uuid
            .putLong(tmpId.getMostSignificantBits())
            .putLong(tmpId.getLeastSignificantBits());
        }
    };

    final UUID parentUUID = UUID.randomUUID();
    System.out.println(parentUUID.toString());

    for (int i = 0; i < 1000; i++) {
        final long childId = Hashing.murmur3_128().newHasher()
                                .putObject(parentUUID, UUID_FUNNEL)
                                .hash().asLong();
        System.out.println(childId);
    }
}

このアイデアについてどう思いますか?どんな提案でも大歓迎です。

私はすでにこの質問を読みました: UUID を使用して一意の Long を生成する方法

4

1 に答える 1

3

これは本当にうまくいきません。確かにランダムに勝るものはありませんlong

  • なしtmpId: をハッシュするだけparentUUIDなので、同じ親のすべての子は同じになりlongます。
  • With tmpId: すべての作業を使用するUUID.randomUUID().getLeastSignificantBits()か、単にrandom.nextLong()保存することができます (ランダムな値をハッシュすると、何を追加してもランダムな結果になります)。

私は1人だけでなく複数のクライアントを持っています。

次に、一意のサーバーに問い合わせます。これには、 hi-lo アルゴリズムを使用して簡単に最小化できるオーバーヘッドが含まれます。

DB レベルでは、子 ID は一意でなければなりません。

次に、それを忘れて、DB に ID を生成させます。すべてのDBには、まさにこれを意図したAUTOINCREMENTまたはSEQUENCEがあります。

DB にアクセスする前にクライアントで ID が必要な場合は、DB に問い合わせてください (オーバーヘッドを最小限に抑えるために、hi-lo アルゴリズムを使用します)。

オフライン作業

私はちょうどあなたのコメントを見ました:

クライアントは、次の ID を取得するためにサーバーにアクセスするべきではありません。オフラインで作業できる必要があります。

これは大きな苦痛です。あなたができるハッシュは、ランダムよりも優れていることはありませんlong

  • 100 万個のランダムなlongs のセットの衝突確率は約1e-6であり、これは許容できる可能性があります。誕生日のパラドックスにより、確率は設定サイズに応じて2 次的に増加することに注意してください。
  • オフラインで作成されたエンティティを ID なしで (他の識別子を使用して) 処理しようとすることもできますが、これは大きな苦痛のように思えます。
  • 各クライアントにいくつかの ID を事前に割り当てることができます。これは無駄に思えますが、100 万のクライアントごとに 100 の ID を事前に割り当てても、使用できるすべての ID の 5% 未満しか使用しません。
  • random UUIDs に切り替えることができます。それらは 128 ビット長であるため、数十億の ID であっても衝突の可能性は事実上ゼロです。
于 2017-01-13T17:50:39.230 に答える