2012-03-31 2 views
2

以下の「つぶやき」の表を検討してください:実際にはデータベース内の重複したつぶやきのログを効率的に検索して保持するにはどうすればよいですか?

tweet_id user_id text  
---------------------------- 
1  1  lorem ipsum 
2  1  lorem ipsum 
3  2  pear 
4  1  dolor 
5  3  foo 
6  1  dolor 
7  1  dolor 
8  3  bar 
9  3  baz 
10  4  happy 
11  4  happy 
12  2  apple 
13  3  foo 
14  4  happy 

を、表には、約80,000ユーザーからのつぶやきの何百万人が含まれています。そこにいるユーザーの多くはスパムアカウントですが、手で識別するのは難しいです。経験則として、スパムアカウントは同じメッセージを少なくとも3回送信します。

duplicate_id user_id text   cnt  duplicate_id tweet_id 
--------------------------------------  ---------------------- 
1   1  lorem ipsum 2   1    1 
2   1  dolor  3   1    2 
3   2  pear   1   2    4 
4   2  apple  1   2    6 
5   3  foo   2   2    7 
6   3  bar   1   3    3 
7   3  baz   1   4    12 
8   4  happy  3   5    5 
              5    13 
              6    8 
              7    9 
              8    10 
              8    11 
              8    14 

私は今、非常に簡単にソート上のインスタンスのためにCNT、およびユーザーが最も重複を投稿するかを確認することができます:私は、次の表の右に左に、「重複」や「duplicates_tweets」を埋めるためにしたい理由ですメッセージ。私の質問は、しかし、これについて最も効率的に行く方法です。言い換えれば、どのようなクエリがこれらのテーブルを満たすのに最も効率的でしょうか?また、SQLだけでも可能ですか?例えば、 "つぶやき"データベースからツイートを取得したり、重複をスキャンしたり、テーブルを埋め込んだり、次のツイートに移ったりするために、PHPを仲介者として使用する必要がありますか?私はこれが年を取って終わるのを恐れているので、どんな助けも大歓迎です!

答えて

1

REPLACE duplicates 
SELECT user_id, text 
FROM (SELECT user_id, text, count(1) as count 
FROM tweets 
GROUP BY user_id, text 
HAVING count(1) > 2)) 
0

新しいツイートを挿入する前に、そのツイートが既に存在するかどうかを確認してください。その場合は、ツイートを挿入してduplicatesとduplicates_tweetsテーブルに挿入します。またはツイートテーブルの挿入時にトリガーを使用します。

+0

つぶやく表は現状のままであり、研究プロジェクトの一部です。新しいツイートは挿入されません:-) – Pr0no

1

スパムの可能性のあるつぶやきのリストを抜き出したいだけですか?あなたはこのクエリを使用することができたときに述べたクリス・Kとして、あなたが本当にduplicate_tweetsテーブルが必要なのですが、あなたはその後、(duplicate_tweetsテーブルを結果を反復処理するためにPHPを使用してINSERT/UPDATEでき

SELECT 
    user_id, 
    text, 
    COUNT(DISTINCT tweet_id) 
FROM 
    tweets 
GROUP BY 
    user_id, 
    text 
HAVING 
    COUNT(DISTINCT tweet_id) >= 3 

:これを試してみてください?)。

あなたがキーに基づいて新しい行を更新または挿入するにはMySQLでは REPLACE機能を使用することができます
+0

あなたの質問に答えるには - テーブルのサイズのため、このクエリは完了するまでに数時間かかるでしょう。私はむしろ1000ユーザーの増分でクエリを実行し、結果をテーブルに格納したいと思います。 – Pr0no

+0

申し訳ありませんが、私は「完了するまでの時間」は信じていません。私は適切にクエリを構成することによって、数千のレコードから1秒未満に「完了までの時間」を変えました。 MySqlは、わかりにくいサイズのデータ​​セットを処理するように設計されています。 「時間が完了するまで」が過ぎていない場合は、サンプルデータを使用して新しい質問を投稿し、MySqlクエリーの作成に役立ててください。彼らの筋肉を曲げるのが大好きな十分な達人がいます。答えは来るべきものではないはずです。 –

1

私は@MichaelRushtonと@Kostaが答えたものと同意するが、あなたはいけない場合、私は疑問に思って全く別のテーブルが必要ですか?問合せを作成する場合は、最初の表に求めている知識を尋ねることができます。私は特にトリガーが好きです。

2

おそらく、あなたはuser_idのことで、テーブル「つぶやき」を並べ替えることができ、その後、テキストで:

SELECT * FROM tweets ORDER BY user_id DESC, text DESC 

その後、あなたは、PHPで結果を反復処理することができます。

<?php 
// ... 
$lastuser = -1; 
$lasttext = ""; 
$ids = array(); 
while ($row = mysql_fetch_assoc($result)) { 
    if($row['user_id'] != $lastuser || $row['text'] != $lasttext) { 
     $ids = array(); 
    } 
    $ids[] = $row['id']; 
    if(count($ids) >= 3) { 
     // flag items as spam 
    } 
    $lastuser = $row['user_id']; 
    $lasttext = $row['text']; 
} 
?> 

をあなたがインデックスを使用している場合あなたのMySQLデータベースでは、約N * log(N)でN個のつぶやきを処理できるはずです。

関連する問題