【发布时间】:2011-01-14 06:08:36
【问题描述】:
我有一个包含 3 列的表 - id (pk)、pageId (fk)、名称。我有一个 php 脚本,它将大约 5000 条记录转储到表中,其中大约一半是重复的,具有相同的 pageId 和名称。 pageId 和 name 的组合应该是唯一的。当我在 php 中循环脚本时,防止将重复项保存到表中的最佳方法是什么?
【问题讨论】:
我有一个包含 3 列的表 - id (pk)、pageId (fk)、名称。我有一个 php 脚本,它将大约 5000 条记录转储到表中,其中大约一半是重复的,具有相同的 pageId 和名称。 pageId 和 name 的组合应该是唯一的。当我在 php 中循环脚本时,防止将重复项保存到表中的最佳方法是什么?
【问题讨论】:
您可以将 PageID 和 Name 设置为 MySQL 数据库中的唯一索引。这样插入行时会报错,PHP可以忽略,直接进入下一行即可。
这假设您正在单独插入行。又名:
foreach($large_data as $fields)
{
mysql_query("INSERT INTO TABLE (`Something`) VALUES('".$fields['something']."');
}
【讨论】:
INSERT IGNORE 功能一样简单时。此外,当大容量插入语法可用时,在循环中插入效率很低。
从mysql的角度来看你可以做
alter table YOURTABLE add unique index(pageId, name);
如果你的措辞是正确的,并且你想用 php 来做,你可以做
$already_done = array();
foreach ($records as $record)
{
$unique_hash = md5($record['name'].$record['pageId']);
if (!in_array($unique_hash, $already_done))
{
$already_done[] = $unique_hash;
// sql insert here
}
}
无论哪种方式,你都应该做得很好。
【讨论】:
$already_done中不会出现这些记录。
您也可以使用 mysql 忽略错误:INSERT IGNORE INTO TABLE ...它将忽略关键错误,跳过该插入并继续下一个。
【讨论】:
第一步是在表上设置一个唯一键:
ALTER TABLE thetable ADD UNIQUE INDEX(pageid, name);
然后你必须决定当有重复时你想做什么。你应该:
忽略它?
INSERT IGNORE INTO thetable (pageid, name) VALUES (1, "foo"), (1, "foo");
覆盖之前输入的记录?
INSERT INTO thetable (pageid, name, somefield)
VALUES (1, "foo", "first")
ON DUPLICATE KEY UPDATE (somefield = 'first')
INSERT INTO thetable (pageid, name, somefield)
VALUES (1, "foo", "second")
ON DUPLICATE KEY UPDATE (somefield = 'second')
更新一些计数器?
INSERT INTO thetable (pageid, name)
VALUES (1, "foo"), (1, "foo")
ON DUPLICATE KEY UPDATE (pagecount = pagecount + 1)
【讨论】: