1

私が検索して見つけたものはすべてまだ機能していません。これは、phpスクリプトを介して、表示されているものとは異なる方法でテーブルにアクセスしているためです。とにかく、私はフィードをWebサイトから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] ADD UNIQUE INDEX UNIQUE_INDEX([FIELDNAME])

これは、重複させたくないフィールドに一意のインデックスを作成することです。無視構文は、MySQLが重複にヒットしたときに停止してエラーを表示しないように指示します。これは、テーブルをダンプしてリロードするよりもはるかに簡単です。また、新しい重複が追加されないように、一意のインデックスが追加されます。INSERTをINSERTIGNOREに変更するだけです。

これも機能しますが、それほどエレガントではありません。

delete from [tablename] where fieldname in(selecta。[fieldname]from(select [fieldname] from [tablename] group by [fieldname] has 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テーブルのようなentries_newというテーブルが作成されます。items_newにデータを1回挿入してから、古いテーブルの名前をentries_backupに変更し、新しいテーブルの名前をentriesに変更します。

このシーケンス全体をトランザクションにまとめることを検討することもできます。

于 2012-11-20T18:57:47.477 に答える