web-dev-qa-db-ja.com

大規模なデータ重複排除を行うにはどうすればよいですか?

efficientデータ重複排除を行うモジュールを開発するか、少なくとも概念化する必要があります。すでに何百万ものデータレコードがあるとします。別の100 mnレコードを挿入し、結果のデータセットに重複レコードがないことを確認することは、モジュールがトップレベルで行う必要があることです。これは、レコードが重複しているかどうかを決定するフィールドで比較することを意味する場合があります。しかし、このアプローチは、何百万ものレコードについて話しているとき、連続的に取られて、本当に素朴です。

実行可能なアプローチは何だと思いますか?ハッシング?分割統治型アルゴリズムを使用して並列処理を活用する私はこれらを頭の中に持っていますが、それは本当にそのようなスケールでめまいがします。

また、私が使用できるWeb上のリソースへのポインタを投稿してください-私は、彼らのデータベースの「最高のデータ重複排除機能」について言っている議論やベンダーを見つけることができました。

6
yati sagade

ハッシング?

必須。

並列処理を利用するために分割統治型アルゴリズムを使用していますか?

必要であれば。

このことを考慮。

すでに数百万の行がDBにあります。各行には、(理想的には)数値である単一の代理PKフィールドが必要です。各行には、重複検出に使用されるキーフィールドもあります。

  1. さまざまな比較キーフィールドのハッシュを計算します。そのハッシュとPKをメモリ内のハッシュマップ(またはツリーマップ)にロードします。これは、200万メモリの数メガバイトです。合理的に現代的なプロセッサーではほとんど何もありません。最も遅い部分は、数百万行のハッシュの計算です。

  2. 着信する各行は、ハッシュマップに対してチェックされます。マップ内にある場合、比較キーは重複を示します。マップにない場合は、問題ありません。

それはほとんどの拠点をカバーするはずです。 「偽陽性」衝突の確率は本当に小さいです。そして、(重複の可能性がある場合)チェックをやり直して、それらのキーが実際に重複であることを確認します。

比較キーフィールドが適切なキーである場合、それらは更新できません。データベース外部のPKキーハッシュマップ全体を非正規化し、再構築を回避できます。

比較キーフィールドが属性である(そして更新できる)場合、ハッシュ値の非正規化を適切に処理する必要があります。比較キーを変更すると、ハッシュ値が変更されます。更新時にそれを計算し、この変更の記念品を保存して、比較ハッシュをゼロから再構築せずに微調整できるようにします。

4
S.Lott

ハッシュが道だと思います。クイック検索とクイック挿入。私はすでに直接試してみました。 1億件のレコードは私にはそれほど多くないように見えますが、もちろん、何時間もかかります。

必要に応じて、ワークロードを分割する1つの方法は、データをハッシュのバンドルに分割することです。たとえば、PC番号ihash_value % N == iを持つすべてのレコードを読み取り、次にhash_value % N == iを持つすべての追加レコードを挿入/拒否します。完了したら、N個のデータセットをマージすると、結果が得られます。

編集:

少し効率的にする1つの方法は、2つのハッシュを使用することです。たとえば、単一のフィールドの迅速で簡単なハッシュは、クイックフィルタリングに使用されますhash % N == i。そして、データベース自体への実際の挿入/検索のための通常のハッシュ。

3
dagnelies

ローリングハッシュ関数 を調べてください。 1つを使用すると、特定のバイトウィンドウのハッシュを計算し、それを1バイト前方に「ロール」して、次のバイトウィンドウのハッシュを見つけることができます。

Hello world
[    ]
 [    ]
  [    ]
   [    ]
    [    ]
     [    ]

タスクがバイナリBLOBで機能するオブジェクトストアを作成することである場合、次のようなことを行うことができます。

  • 固定サイズのチャンクのハッシュテーブルを維持します(この例では、64バイトのチャンクと32ビットのハッシュ)。

  • 新しいblobが挿入されたら、64バイトごとにハッシュし、各チャンクをハッシュテーブルに格納します。ハッシュと文字列の配列としてエンコードしてblobを「圧縮」します。ハッシュの衝突の可能性に注意してください。

    ------------------------------
    [1fedccba][deadbeef][13579ace]
    
  • 後続のblobが挿入されたら、それをロールスルーして、すでに持っているチャンクを見つけます。

    ---------------------------
    [a7ed8842]
     [cb438564]
      [e5fe0527]
       [c2ff4713]
        [1fedccba] *** Chunk matches one we already have.
                  [793bd55d]
                   [45a39f7e]
                    [dace4e10]
                     [ee6fcc7b]
    

この手法を使用すると、挿入や削除、またはシリアライゼーションによるアライメントのバリエーションが存在する場合でも、データのチャンクを重複排除できます。

2
Joey Adams

exactlyである値を重複排除するには、(almostが等しいのではなく) 、強力な十分な cryptographic hash でキー付けされたディクショナリを使用できます。例、PostgreSQLタイプを使用:

CREATE TABLE dictionary (
    sha256 BYTEA PRIMARY KEY,
    value  BYTEA
);

これを行う利点は、ルックアップ操作がはるかに高速になることです。文字列全体(非常に大きくなる可能性がある)を比較するのではなく、256ビット(32バイト)の値を比較するだけです。

これは、同じ SHA-256ハッシュ の2つの異なる文字列に遭遇しないことを前提としています。このような文字列のペアは理論的にはpidgenholeの原理により存在しますが、SHA-256ハッシュは256ビットにすぎませんが、バイト文字列はそれより長くなる可能性があり(通常は長くなります)、そのようなペアは誰も発見していません。

値がバイト文字列でない場合は、 serialize にする方法を見つける必要があります。

1
Joey Adams

MapReduce を使用してみてください。

editこれはmap reduceのwikiエントリです このタスクでmap reduceを使用する方法は次のとおりです:

マッピング関数は、アイテムをそれ自体にマップします(たとえば、ペアを返します)。削減関数は、重複するアイテムのペアの場合、アイテムの1つを削除します。

0
David Weiser