2010-02-08 6 views
30

J'ai une table avec 3 colonnes - id (pk), pageId (fk), nom. J'ai un script php qui déverse environ 5000 enregistrements dans la table, avec environ la moitié étant des doublons, avec le même pageId et le même nom. La combinaison de pageId et de nom doit être unique. Quel est le meilleur moyen d'empêcher les doublons d'être sauvegardés dans la table lorsque je boucle le script en php?Meilleure façon d'éviter l'entrée en double dans la base de données mysql

Répondre

96

La première étape serait de définir une clé unique sur la table:

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

Ensuite, vous devez décider ce que vous voulez faire quand il y a un double. Si vous:

  1. l'ignorer?

    INSERT IGNORE INTO thetable (pageid, name) VALUES (1, "foo"), (1, "foo"); 
    
  2. Remplacer l'enregistrement saisi précédemment?

    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. Mettre à jour un compteur?

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

GRAND merci, c'était une excellente réponse à une question que j'ai étudiée depuis quelque temps ici sur Stack Overlow. – capfu

1

Vous pouvez définir le PageID et le Nom sur un index Unique dans la base de données MySQL. De cette façon, lorsque vous insérez les lignes, cela provoque une erreur, qui peut être ignorée par PHP, et vous pouvez simplement passer à la ligne suivante.

Cela suppose que vous insérez des lignes individuellement. Alias:

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

Intentionnellement permettant mysql_query() pour lancer des avertissements PHP lorsque vous appuyez sur les lignes en double est une sorte de désordre (il encombre votre journal, il est des ressources relativement intensive, etc.). Surtout quand les empêcher en premier lieu est aussi simple que d'utiliser la fonction 'INSERT IGNORE' de MySQL mentionnée dans d'autres solutions. En outre, l'insertion dans une boucle est inefficace lorsque la syntaxe d'insertion en bloc est disponible. –

1

D'un point de MySQL, vous pouvez le faire

alter table YOURTABLE add unique index(pageId, name); 

Si votre texte est correct et que vous voulez faire de php vous pouvez faire

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

de toute façon ceux-ci devraient Est-ce que vous allez bien?

+1

Bien sûr, s'il y a déjà des enregistrements dans la table * avant * le démarrage du script, ceux-ci n'apparaîtront pas dans '$ already_done'. –

3

Vous pouvez également ignorer l'erreur avec mysql: INSERT IGNORE INTO TABLE ... il ignorera l'erreur de clé, passera au-dessus de cet insert et passera au suivant.

Questions connexes