web-dev-qa-db-fra.com

MySQL: ALTER IGNORE TABLE donne "Violation de contrainte d'intégrité"

J'essaie de supprimer les doublons d'une table MySQL en utilisant ALTER IGNORE TABLE + une clé UNIQUE. La documentation MySQL dit:

IGNORE est une extension MySQL du SQL standard. Il contrôle le fonctionnement d'ALTER TABLE s'il existe des doublons sur des clés uniques dans la nouvelle table ou si des avertissements se produisent lorsque le mode strict est activé. Si IGNORE n'est pas spécifié, la copie est abandonnée et annulée si des erreurs de clé en double se produisent. Si IGNORE est spécifié, seule la première ligne est utilisée des lignes avec des doublons sur une clé unique. Les autres lignes en conflit sont supprimées. Les valeurs incorrectes sont tronquées à la valeur acceptable correspondante la plus proche.

Lorsque j'exécute la requête ...

ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field)

... J'obtiens toujours l'erreur # 1062 - Entrée en double 'blabla' pour la clé 'dupidx'.

47
Philippe Gerber

L'extension du mot clé IGNORE à MySQL semble avoir un bug dans la version InnoDB sur certaines versions de MySQL.

Vous pouvez toujours, convertir en MyISAM, IGNORE-ADD l'index, puis reconvertir en InnoDB

ALTER TABLE table ENGINE MyISAM;
ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field);
ALTER TABLE table ENGINE InnoDB;

Notez que si vous avez des contraintes de clé étrangère, cela ne fonctionnera pas, vous devrez d'abord les supprimer et les rajouter plus tard.

96
Emma

Ou essayez de définir la session old_alter_table = 1 (N'oubliez pas de la réinitialiser!)

Voir: http://mysqlolyk.wordpress.com/2012/02/18/alter-ignore-table-add-index-always-give-errors/

26
Jay Julian Payne

Le problème est que vous avez des données en double dans le champ que vous essayez d'indexer. Vous devrez supprimer les doublons incriminés avant de pouvoir ajouter un index unique.

Une façon consiste à procéder comme suit:

   CREATE TABLE tmp_table LIKE table;
   ALTER IGNORE TABLE tmp_table ADD UNIQUE INDEX dupidx (field);
   INSERT IGNORE INTO tmp_table SELECT * FROM table;
   DROP TABLE table;
   RENAME TABLE tmp_table TO table;

cela vous permet d'insérer uniquement les données uniques dans le tableau

3
Glen Solsberry