У меня есть таблица с тремя столбцами - id (pk), pageId (fk), name. У меня есть php-скрипт, который сбрасывает около 5000 записей в таблицу, причем примерно половина дубликатов, с одинаковым именем страницы и именем. Комбинация pageId и name должна быть уникальной. Каков наилучший способ предотвратить дублирование, сохраняемое в таблице, когда я прохожу через скрипт в php?Лучший способ избежать дублирования ввода в базу данных mysql
ответ
Первого шаг должен были бы установить уникальный ключ на столе:
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)
Вы можете установить идентификатор страницы и имени для уникального индекса в базе данных MySQL. Таким образом, когда вы вставляете строки, это приведет к ошибке, которую PHP может игнорировать, и вы можете просто перейти к следующей строке.
Предполагается, что вы вставляете строки отдельно. AKA:
foreach($large_data as $fields)
{
mysql_query("INSERT INTO TABLE (`Something`) VALUES('".$fields['something']."');
}
Преднамеренно позволяет mysql_query(), чтобы бросить PHP предупреждения, когда вы попали повторяющиеся строки вроде грязного (это загромождает ваш журнал, это относительно ресурсоемким и т.д.). Особенно, когда их предотвращать, в первую очередь так же просто, как использование функции MySQL INSERT IGNORE, упомянутой в других решениях. Кроме того, вставка в цикл неэффективна, когда доступен синтаксис большой вставки. –
С точки тузд вы можете сделать
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 ... он будет игнорировать ключевую ошибку, пропустить эту вставку и перейти к следующему.
БОЛЬШИЕ Спасибо, это был отличный ответ на вопрос, который я исследовал некоторое время здесь, на Stack Overlow. – capfu