Juste pour ajouter ma solution car j'ai eu un problème similaire.
TL; DR
- Recréez la table avec la même spécification de clé étrangère mais avec un nom différent de celui détenu précédemment par la table.
- Supprimez la table résultante (supprimera également la clé étrangère orpheline d'origine)
- Recréer une table avec une clé étrangère originale ou sans clé étrangère
Détail
J'ai rencontré la situation désagréable où une instruction ALTER TABLE a échoué car une clé étrangère n'a pas été supprimée plus tôt. Cela a conduit à des incohérences dans le dictionnaire de données InnoDB (probablement en raison de http://bugs.mysql.com/bug.php?id=58215 ).
Question connexe ici: /programming/16857451/error-in-foreign-key-constraint-on-a-droped-table
mysql> ALTER TABLE `visits` CHANGE COLUMN `variation_visitor_id` `variation_visitor_id` INT(11) NOT NULL ;
Erreur lors du renommage de './db/#sql-482c_8448f' en './db/visits' (errno: 150)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint of table db/visits:
FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definitippon.
Comme je n'ai pas pu récupérer la table # sql-482c_8448f aux visites, j'ai décidé de la réimporter à partir d'une sauvegarde effectuée juste avant la modification. Mais cela a échoué. Enquête:
- La contrainte a été supprimée de INFORMATION_SCHEMA.TABLE_CONSTRAINTS et INFORMATION_SCHEMA.STATISTICS
- Mais la contrainte était toujours visible dans INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
- La table n'existait pas, je n'ai donc pas pu supprimer la clé étrangère
- Je n'ai pas pu créer la table sans erreur
SQL / Erreurs
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE ID='db/fk_visits_variations_visitors1';
+-----------------------------------+-----------+------------------------+--------+------+
| ID | FOR_NAME | REF_NAME | N_COLS | TYPE |
+-----------------------------------+-----------+------------------------+--------+------+
| db/fk_visits_variations_visitors1 | db/visits | db/variations_visitors | 1 | 48 |
+-----------------------------------+-----------+------------------------+--------+------+
La tentative de recréation de la table sans la clé étrangère a provoqué une erreur 150
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 150)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint of table db/visits:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "fk_visits_variations_visitors1" FOREIGN KEY ("variation_visitor_id") REFERENCES "variations_visitors" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
Essayer de le créer avec a provoqué une erreur 121
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
KEY `fk_visits_variations_visitors1` (`variation_visitor_id`),
CONSTRAINT `fk_visits_variations_visitors1` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 121)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint creation for table `db`.`visits`.
A foreign key constraint of name `db`.`fk_visits_variations_visitors1`
already exists. (Note that internally InnoDB adds 'databasename'
in front of the user-defined constraint name.)
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
> the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.
Finalement, j'ai utilisé un nouveau nom de clé étrangère. Je ne m'attendais pas à ce que cela fonctionne, mais cela a permis de créer la table.
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
KEY `fk_visits_variations_visitors2` (`variation_visitor_id`),
CONSTRAINT `fk_visits_variations_visitors2` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
Il suffit de supprimer la table après avoir supprimé l'enregistrement erroné dans INFORMATION_SCHEMA.INNODB_SYS_FOREIGN, permettant une importation avec le nom de clé étrangère d'origine.
my_user
mais l'erreur concernemy_db.user
...