2010-02-08 7 views
30

У меня есть таблица с тремя столбцами - id (pk), pageId (fk), name. У меня есть php-скрипт, который сбрасывает около 5000 записей в таблицу, причем примерно половина дубликатов, с одинаковым именем страницы и именем. Комбинация pageId и name должна быть уникальной. Каков наилучший способ предотвратить дублирование, сохраняемое в таблице, когда я прохожу через скрипт в php?Лучший способ избежать дублирования ввода в базу данных mysql

ответ

96

Первого шаг должен были бы установить уникальный ключ на столе:

ALTER TABLE thetable ADD UNIQUE INDEX(pageid, name); 

Затем вы должны решить, что вы хотите делать, когда есть дубликат. Если вы:

  1. игнорировать это?

    INSERT IGNORE INTO thetable (pageid, name) VALUES (1, "foo"), (1, "foo"); 
    
  2. Записать ранее введенную запись?

    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') 
    
  3. Обновить счетчик?

    INSERT INTO thetable (pageid, name) 
    VALUES (1, "foo"), (1, "foo") 
    ON DUPLICATE KEY UPDATE (pagecount = pagecount + 1) 
    
+3

БОЛЬШИЕ Спасибо, это был отличный ответ на вопрос, который я исследовал некоторое время здесь, на Stack Overlow. – capfu

1

Вы можете установить идентификатор страницы и имени для уникального индекса в базе данных MySQL. Таким образом, когда вы вставляете строки, это приведет к ошибке, которую PHP может игнорировать, и вы можете просто перейти к следующей строке.

Предполагается, что вы вставляете строки отдельно. AKA:

foreach($large_data as $fields) 
{ 
    mysql_query("INSERT INTO TABLE (`Something`) VALUES('".$fields['something']."'); 
} 
+1

Преднамеренно позволяет mysql_query(), чтобы бросить PHP предупреждения, когда вы попали повторяющиеся строки вроде грязного (это загромождает ваш журнал, это относительно ресурсоемким и т.д.). Особенно, когда их предотвращать, в первую очередь так же просто, как использование функции MySQL INSERT IGNORE, упомянутой в других решениях. Кроме того, вставка в цикл неэффективна, когда доступен синтаксис большой вставки. –

1

С точки тузд вы можете сделать

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 
    } 
} 

либо способом те должны ты просто в порядке.

+1

Конечно, если в таблице уже есть записи * до того, как * начнется скрипт, они не появятся в '$ already_done'. –

3

Вы также можете проигнорировать ошибку с помощью mysql: INSERT IGNORE INTO TABLE ... он будет игнорировать ключевую ошибку, пропустить эту вставку и перейти к следующему.