3

大きなテキストファイルがあるとしましょう。各行には、電子メールIDとその他の情報(たとえば、製品ID)が含まれています。ファイルに数百万の行があると仮定します。このデータをデータベースにロードする必要があります。データを効率的に重複排除する(つまり、重複を排除する)にはどうすればよいですか?

4

6 に答える 6

8

非常識な行数

  • Map&Reduce フレームワーク (Hadoop など) を使用します。これは本格的な分散コンピューティングであるため、数 TB のデータがない限りやり過ぎです。( j/k :) )

すべての行をメモリに収めることができません

  • 結果も収まりません: マージソートを使用して、中間データをディスクに永続化します。マージすると、重複を破棄できます (おそらく、このサンプルが役立ちます)。必要に応じて、これをマルチスレッドにすることができます。
  • 結果は収まります: メモリ内のすべてを読み取って HashSet (以下を参照) に入れる代わりに、行反復子または何かを使用して、この HashSet に追加し続けることができます。ConcurrentHashMap を使用し、複数のスレッドを使用してファイルを読み取り、このマップに追加できます。もう 1 つのマルチスレッド オプションは、ConcurrentSkipListSet を使用することです。この場合、 equals()/hashCode() の代わりに compareTo() を実装し (compareTo()==0 は重複を意味します)、この SortedSet に追加し続けます。

メモリに収まる

  • データを保持するオブジェクトを設計し、適切な equals()/hashCode() メソッドを実装して、それらすべてを HashSet に入れます。
  • または、上記の方法を使用します (ただし、おそらくディスクに保持したくないでしょう)。

ああ、もし私があなただったら、とにかくDBに一意の制約を置きます...

于 2010-02-25T07:35:59.890 に答える
1

Duke ( https://github.com/larsga/Duke ) を見てみましょう。これは、Java で書かれた高速重複排除およびレコード リンケージ エンジンです。Lucene を使用してインデックスを作成し、比較の数を減らします (容認できないデカルト積の比較を避けるため)。最も一般的なアルゴリズム (編集距離、ジャロ ウィンクラーなど) をサポートし、非常に拡張可能で構成可能です。

于 2014-05-08T16:15:45.373 に答える
1

私は明白な答えから始めます。ハッシュマップを作成し、メール ID をキーとして入力し、残りの情報を値に入力します (または、すべての情報を保持するオブジェクトを作成します)。新しい行に移動したら、キーが存在するかどうかを確認し、存在する場合は次の行に移動します。最後に、HashMap を使用してすべての SQL ステートメントを書き出します。「無数の」行がある場合、メモリの制約が重要になるというeqbridgesに同意します。

于 2010-02-25T05:40:26.677 に答える
1

2 つのオプションがあります。

  1. Javaでそれを行う:テスト用のようなものをまとめることができHashSetます-セットに存在しない場合に、入ってくる各アイテムの電子メールIDを追加します。

  2. データベースで実行します。重複がテーブルに追加されないように、テーブルに一意の制約を設定します。これに追加されたボーナスは、プロセスを繰り返して、以前の実行から重複を削除できることです。

于 2010-02-25T05:43:44.590 に答える
0

メールと製品 ID でテーブルのインデックスを作成できませんか? 次に、インデックスによる読み取りにより、電子メールまたは電子メール + prodId のいずれかの重複が順次読み取りによって容易に識別され、前のレコードと単純に一致する必要があります。

于 2010-02-25T07:30:04.500 に答える
0

問題は、抽出、変換、読み込み (ETL)アプローチで解決できます。

  • インポート スキーマにデータをロードします。
  • データに対して必要なすべての変換を行います。
  • 次に、それをターゲット データベース スキーマにロードします。

これは手動で行うことも、ETL ツールを使用することもできます。

于 2010-02-25T08:02:54.647 に答える