2010-02-08 18 views
30

Tengo una tabla con 3 columnas: id (pk), pageId (fk), name. Tengo un script php que vierte unos 5000 registros en la tabla, y aproximadamente la mitad son duplicados, con el mismo ID de página y nombre. La combinación de pageId y nombre debe ser única. ¿Cuál es la mejor manera de evitar que los duplicados se guarden en la tabla mientras recorro el script en php?La mejor manera de evitar la entrada duplicada en la base de datos mysql

Respuesta

96

El primer paso sería establecer una clave única de la tabla:

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

entonces usted tiene que decidir lo que quiere hacer cuando hay un duplicado. ¿Debe usted:

  1. ¿ignorarlo?

    INSERT IGNORE INTO thetable (pageid, name) VALUES (1, "foo"), (1, "foo"); 
    
  2. ¿Sobrescribe el registro ingresado anteriormente?

    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. ¿Hay alguna pregunta?

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

GRANDES gracias, esta fue una excelente respuesta a una pregunta que investigué durante un tiempo aquí en Stack Overlow. – capfu

1

Puede establecer el PageID y el Nombre en un índice único en la base de datos MySQL. De esta forma, cuando insertas las filas, se producirá un error que PHP puede ignorar, y puedes ir a la siguiente fila.

Esto supone que está insertando filas individualmente. También conocido como:

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

permitiendo intencionalmente mysql_query() para lanzar advertencias PHP cuando se pulse filas duplicadas es una especie de desordenado (it estorba su registro, es relativamente intensiva de recursos, etc.). Especialmente cuando prevenirlos en primer lugar es tan simple como usar la función 'INSERT IGNORE' de MySQL mencionada en otras soluciones. Además, insertar en un bucle es ineficaz cuando la sintaxis de inserción masiva está disponible. –

1

Desde un punto de MySQL puede hacer

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

Si su redacción es correcta y desea hacerlo desde PHP que puede hacer

$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 cualquier manera los debe ¿estás bien?

+1

Por supuesto, si ya hay registros en la tabla * antes * de que se inicie la secuencia de comandos, esos no aparecerían en '$ already_done'. –

3

También puede ignorar el error con mysql: INSERT IGNORE INTO TABLE ... ignorará el error clave, omita ese inserto y pase al siguiente.

Cuestiones relacionadas