Php 如何在数据库中高效地查找并保存重复推文的日志? 请考虑以下的“推特”表:
事实上,该表包含了来自约80000名用户的数百万条推文。很多用户都有垃圾邮件账户,但很难用手识别。根据经验,垃圾邮件帐户至少发布同一邮件3次。这就是为什么我要填写下表,左边是“duplicates”,右边是“duplicates_tweets”:Php 如何在数据库中高效地查找并保存重复推文的日志? 请考虑以下的“推特”表:,php,mysql,sql,Php,Mysql,Sql,事实上,该表包含了来自约80000名用户的数百万条推文。很多用户都有垃圾邮件账户,但很难用手识别。根据经验,垃圾邮件帐户至少发布同一邮件3次。这就是为什么我要填写下表,左边是“duplicates”,右边是“duplicates_tweets”: duplicate_id user_id text cnt duplicate_id tweet_id -------------------------------------- -------------
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上排序,并查看哪些用户发布的重复消息最多。然而,我的问题是如何最有效地进行这项工作。换句话说:什么查询最有效地填充这些表?仅仅使用SQL是可能的,还是我应该使用PHP作为中介,例如从“tweets”数据库中获取一条tweet,扫描重复的tweet,填充表格,然后转到下一条tweet?恐怕这需要很长时间才能完成,因此非常感谢您的帮助 在插入新tweet之前,请检查tweets表是否已经存在此类tweet。如果是,请插入tweet并将其插入duplicates和duplicates_tweets表中。或者在insert for tweets表上使用触发器。您是否只想拉出可能的垃圾邮件tweet列表?试试这个:
SELECT
user_id,
text,
COUNT(DISTINCT tweet_id)
FROM
tweets
GROUP BY
user_id,
text
HAVING
COUNT(DISTINCT tweet_id) >= 3
然后,您可以使用PHP对结果进行迭代,并插入/更新一个重复的tweets
表(尽管如Chris K所述,当您可以使用此查询时,您真的需要一个重复的tweets
表吗?).您可以使用MySQL中的函数根据键更新或插入新行:
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))
我同意@MichaelRushton和@Kosta的回答,但我想知道你是否根本不需要另一张桌子?如果构建查询,您可以向第一个表询问您正在寻找的知识。我特别喜欢触发器。也许,您可以按用户id然后按文本对表“tweets”进行排序:
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条tweets。tweets表按原样处理,并且是研究项目的一部分。不会插入新的推文:-)回答您的问题-由于表的大小,此查询需要数小时才能完成。我宁愿以1000个用户的增量执行查询,并将结果存储在一个表中。对不起,我不相信“需要几个小时才能完成”。通过正确地构造查询,我将“完成的分钟数”从几千条记录变成了不到一秒的时间。MySql被设计用来处理无法理解的数据集。如果“需要几个小时才能完成”一点也不夸张,那么就用示例数据发布一个新问题,并寻求帮助构建MySql查询。这里有足够多的古鲁喜欢伸展他们的肌肉;答案不会太长。
<?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'];
}
?>