2011-01-11 2 views
6

私は、MySQLデータベースとインターフェイスする電子メールアプリケーションを作成しています。私は自分のデータをソーシングしている2つのテーブルを持っていますが、そのうちの1つはサブスクリプションを含み、もう1つは標準ユーザーテーブルです。今のところ、私は電子メールオブジェクトへのポインタのベクトルを作成し、最初にその中に登録されていないすべての電子メールを格納しています。私は標準のSQLループを持っています。そこでは、電子メールが購読中止ベクトルにないかどうかを確認してから、それをグローバルな電子メール送信ベクトルに追加します。私の質問は、これを行うより効率的な方法がありますか?私はシステム内のすべての電子メールに対してunsubベクトルを検索しなければなりません。検索のためのより良い構造はありますか?そして、ユニークな値のコレクションを維持するためのより良い構造ですか?おそらくすでに値が入っていれば単にその値を破棄するのでしょうか?最速のC++コンテナ:ユニークな値

+1

DVKとダニエルTrebbienが正しい:それはほとんどです確かにDBでこれを行うより良い。これが不可能だと私はあなたを信じていません - スキーマの関連部分を投稿してください。 –

+0

ユーザがメールを受信したいかどうかをチェックする前に電子メールを生成するのはなぜですか?あなたはここで特別な仕事をしています... –

+0

@Matthieu:私は電子メールのコンテンツを生成していない、私は相互参照の電子メールアドレスを収集しています。 – Josh

答えて

6

C++標準ライブラリの実装でサポートされている場合は、std::unordered_setまたはstd::hash_setを使用することを検討してください。

オーバーヘッドは高くなる可能性がありますが(オブジェクトのハッシュを生成するコストとオブジェクトの2つを数回比較するコストによります)、std::setを使用することもできます。

setまたはunordered_setのようなノードベースのコンテナを使用する場合は、vectorからの削除と比較して要素の削除が比較的安価であるという利点もあります。

+1

'std :: unordered_set'または' std :: tr1 :: unordered_set'を意味すると思います。 –

+2

また、 'std :: hash_set'は標準の一部ではありません。もし' boost :: unordered_set' TR1またはC++ 0xを持たない。 –

+0

@エヴァン:そうです。私は 'std :: unordered_set'を意味しました。私は今朝コーヒーを飲みませんでした。ほとんどの標準ライブラリの実装は、ある形式か別の形式で 'hash_set'を提供します。 –

4

std::setにメールアドレスを保存するか、std::set_difference()を使用してください。

+0

+1の 'set_difference'(ベーキングされているため)ですが、トラバースする方が速いはずです(より良いメモリのローカリティ)ので、セットではなく3つの(ソートされた)ベクタを使うことをお勧めします。また、サイズが大きく、Dirkumware(およびその小さなバケツ)を使用していない場合、 'deque'も考慮に入れることができます。 –

+0

@Matthieu: 'set_difference'を使うときはもちろん、ソートされたベクトルを使います。ほかに何か? –

+0

ノードベースのコンテナは痛いほど遅くなることがあります。 –

5
  1. このようなタスク(操作の設定)は、それらを実行するためには何が重要なのでしょうか?

    など。線に沿って何か:

    SELECT email FROM all_emails_table e WHERE NOT EXISTS (
        SELECT 1 FROM unsubscribed u where e.email=u.email 
    ) 
    
  2. あなたがアルゴリズムをしたい場合は、電子メールのリストとORDEREDリストなどunsubscriptionsのリストの両方を取得することにより、高速、これを行うことができます。それから、あなたは電子メールリスト(注文されています)を通過することができます。そうすれば、登録解除リストを滑らせることができます。あなたの現在の要素のようなO(M * N)の代わりにO(M + N)である

  3. あなたはサブスクライブされていない電子メールアドレスから1にマップするハッシュマップを実行します。次に、find()をコールして、適切なハッシュ実装が正しいかどうかを調べます。 残念ながら、C++ではハッシュマップ標準はありません。 this SO question for existing implementations(アイデアのカップルSGIのSTL hash_mapとブーストおよび/またはTR1 std::tr1::unordered_mapがある)

    その記事のコメントの一つは、それが標準に追加されますを示しています。C++標準ライブラリテクニカルレポート、「これを念頭に置いて導入されたハッシュテーブルを使用して実装されている、と彼らは今、C++標準の草案に追加された順不同連想コンテナ、。」

+0

残念ながら、テーブルの1つが以前にレイアウトされていたため、私のアプリケーションの一部ではできません。 – Josh

+2

@ Josh:あなたのスキーマの関連部分を投稿しますか?登録されていない電子メールのために別のテーブルがありますか? –

+0

LEFT OUTER JOINを使用してみませんか? '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ –

1

これを行うための最善の方法は、MySQL内にある、私は思います。ユーザーテーブルのスキーマは、別の列、BITの列を使用して変更することができます。さらに良い方法:デフォルトの値がNULLの "date deleted"の列にDATETIMEを追加する。

BIT列を使用して、クエリのようなものになった場合:DATETIME列を使用している場合

SELECT * FROM `users` WHERE `unsubscribed` <> 0b1; 

、クエリが何かのようになり:

SELECT * FROM `users` WHERE `date_unsubscribed` IS NULL; 
+0

また、ユーザーを退会させています。現在のスキーマはメールアドレスの登録を解除しますが、これはまったく同じことではありません。ユーザーが自分のメールアドレスを登録解除されているメールアドレスに変更した場合、メッセージの受信を停止する必要がありますか? OPのアプローチは「はい」と言いますが、これは「いいえ」と言いますが、これは正しい回答である可能性が高いと思います。 –

関連する問題