1

我搜索并找到的所有内容都还没有工作,因为我通过 php 脚本访问表格,并且与我看到的所有内容不同。无论如何,我正在将网站上的 Feed 导入到 mysql 表中。我的表是这样创建的......

$query2 = <<<EOQ
CREATE TABLE IF NOT EXISTS `Entries` (
`feed_id` int(11) NOT NULL,
`item_title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_link` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_date` varchar(40) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
EOQ;
$result = $db_obj->query($query2);

我像这样输入数据....

foreach($rss->channel->item as $Item){
$query5 = <<<EOQ
INSERT INTO Entries (feed_id, item_title, item_link, item_date)
VALUES ('$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;
$result = $db_obj->query($query5);
}

现在,每次从站点导入新提要时,我都想确保删除任何可能已经存在的重复项。我尝试过的一切,尤其是 DISTINCT,都没有为我工作。有谁知道我可以使用什么类型的查询来创建临时表,复制任何不同的行(整个行,如果标题相同但日期不同,我想保留它),删除旧表,然后重命名我想要的夯实表....或类似的东西?

4

3 回答 3

1

首先避免使用重复的行。将任何唯一值变成键。向数据库添加新值时,请使用

REPLACE INTO Entries (feed_id, item_title, item_link, item_date)
VALUES ('$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;

重复的将被自动覆盖。替换很方便,因为当键没有冲突时它就像插入一样工作,但是当有冲突时,它会更新记录并增加任何自动递增的键。

编辑

我一直在鼓吹这件事。这就是我想出的。

在 (feed_id, item_title, item_link, item_date) 上创建多列键的问题在于它将超过 MySQL 中键长度的 1000 字节限制。因此,改为像这样更改您的架构:

CREATE TABLE IF NOT EXISTS `Entries` (
`hash` varchar(32),
`feed_id` int(11) NOT NULL,
`item_title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_link` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_date` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (hash)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

现在,当您存储一个新值时,将这些值的哈希值放在一起:

$hash = md5($get_id . $Item->title . $Item->link . $Item->pubDate);

对于您的插入语句,请使用以下内容:

REPLACE INTO Entries (hash, feed_id, item_title, item_link, item_date)
VALUES ('$hash', '$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;

哈希将是整个记录的唯一表示,并且易于比较以避免重复。现在,当您尝试多次添加同一记录时,它只会替换现有条目,并且您的查询不会失败。作为替代方案,您可以继续使用插入,查询将返回一个错误,您可以随意处理。

于 2012-11-20T18:34:19.200 回答
0

删除重复记录的最快和最简单的方法是发出一个非常简单的命令。

ALTER IGNORE TABLE [TABLENAME] 添加唯一索引UNIQUE_INDEX([FIELDNAME])

这样做是在您不希望有任何重复的字段上创建一个唯一索引。忽略语法指示 MySQL 在遇到重复项时不要停止并显示错误。这比转储和重新加载表要容易得多。它还将添加唯一索引,以便不会添加新的重复项。只需将您的 INSERT 更改为 INSERT IGNORE。

这也可行,但不那么优雅:

delete from [tablename] where fieldname in (select a.[fieldname] from (select [fieldname] from [tablename] group by [fieldname] with count(*) > 1 ) a )

于 2012-11-20T18:51:38.373 回答
0

也许做这样的事情:

$query2 = 'CREATE TABLE entries_new LIKE entries';
$result = $db_obj->query($query2);

$query5 = 'INSERT INTO entries_new (feed_id, item_title, item_link, item_date) VALUES ';
foreach($rss->channel->item as $Item){
    $query5 .= '('$get_id','$Item->title','$Item->link','$Item->pubDate'),';
}
$query5 = rtrim($query5, ',');
$result = $db_obj->query($query5);

$query6 = "RENAME TABLE entries TO entries_backup, entries_new TO entries";
$result = $db_object->query($query6);

这将创建一个名为 entries_new 的表,就像您的条目表一样。在 entry_new 中插入一次数据,然后将旧表重命名为 entries_backup,将新表重命名为条目。

您可能还想考虑将整个序列包装在一个事务中。

于 2012-11-20T18:57:47.477 回答