web-dev-qa-db-fra.com

mysql La contrainte de clé étrangère est une erreur mal formée

J'ai deux tables, table1 est la table parent avec une colonne ID et table2 avec une colonne IDFromTable1 (pas le nom réel) lorsque je mets un FK sur IDFromTable1 à ID dans table1 J'obtiens l'erreur Foreign key constraint is incorrectly formed error. Je voudrais supprimer l'enregistrement de la table 2 si l'enregistrement table1 est supprimé. Merci pour toute aide

ALTER TABLE `table2`  
   ADD CONSTRAINT `FK1` 
      FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`) 
      ON UPDATE CASCADE 
      ON DELETE CASCADE;

Faites-moi savoir si d'autres informations sont nécessaires. Je suis nouveau sur mysql

112
user516883

J'ai rencontré le même problème avec HeidiSQL. L'erreur que vous recevez est très cryptique. Mon problème est que la colonne de clé étrangère et la colonne de référence ne sont pas du même type ou de la même longueur.

La colonne de clé étrangère était SMALLINT(5) UNSIGNED et la colonne référencée était INT(10) UNSIGNED. Une fois que je leur ai donné le même type, la création de clé étrangère a parfaitement fonctionné.

258
Jake Wilson

J'ai eu le même problème lorsque la table parent a été créée à l'aide du moteur MyISAM. C'est une erreur stupide, que j'ai corrigée avec:

ALTER TABLE parent_table ENGINE=InnoDB;
35
Denis Malinovsky

assurez-vous que les colonnes sont identiques (du même type) et si la colonne de référence n'est pas primary_key, assurez-vous qu'elle est INDEXED.

18
Santosh

La syntaxe de définition des clés étrangères est très tolérante, mais pour quiconque s'y intéresse, le fait que les clés étrangères doivent être "du même type" s'applique même au tri, pas seulement au type de données, à la longueur et à la signature de bits.

Ce n'est pas que vous mélangez le classement dans votre modèle (mais vous le feriez?), Mais si c'est le cas, assurez-vous que vos champs de clé primaire et étrangère sont du même type de classement dans phpmyadmin ou Heidi SQL ou tout ce que vous utilisez.

J'espère que cela vous épargne les quatre heures d'essai et d'erreur que cela m'a coûté.

16
user2297047

Juste pour terminer.

Cette erreur peut également être le cas si vous avez une clé étrangère avec VARCHAR (..) et que le jeu de caractères de la table référencée est différent de la table la référençant.

par exemple. VARCHAR (50) dans une table Latin1 est différent de VARCHAR (50) dans une table UTF8.

10
S Doering

J'ai eu le même problème, mais résolu.

Assurez-vous simplement que la colonne 'ID' dans 'table1' aUNIQUEindex!

Et bien sûr, le type et la longueur des colonnes 'ID' et 'IDFromTable1' dans ces deux tables doivent être identiques. Mais vous savez déjà à ce sujet.

10
Renat Gatin

les textes d'erreur mysql ne m'aident pas beaucoup, dans mon cas, la colonne avait la contrainte "not null", aussi le "on delete set null" n'était pas autorisé

6
Luca C.

si tout va bien, ajoutez simplement ->unsigned(); à la fin de foregin key.

si cela ne fonctionne pas, vérifiez le type de données des deux champs. ils doivent être les mêmes.

3
josef

J'ai eu le même problème, les deux colonnes étaient INT (11) NOT NULL mais je ne pouvais pas créer la clé étrangère . Je devais désactiver les vérifications de clés étrangères pour l'exécuter correctement:

SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;

J'espère que ça aide quelqu'un.

2
Takman

Une autre cause probable de l’affichage de cette erreur. L'ordre dans lequel je créais les tables était incorrect. J'essayais de référencer une clé d'une table qui n'était pas encore créée.

2
Kaya Toast

Essayez de courir en suivant:

 show create table Parent 

 // et vérifie si le type des deux tables est identique, comme myISAM ou innoDB, etc
//Autres aspects à vérifier avec ce message d'erreur: les colonnes utilisées en tant que Les clés 
 étrangères doivent être indexées, elles doivent être du même type 
 (si, par exemple, l'une est de type smallint (5) et l'autre de type smallint (6), 
 cela ne fonctionnera pas), et, s’il s’agit d’entiers, ils doivent être non signés .

 // ou rechercher des jeux de caractères
show Les variables telles que "character_set_database"; 
 affichent les variables telles que "collation_database"; 

 // édité: essayez quelque chose comme ceci 
 ALTER TABLE table2 
 ADD CONSTRAINT fk_IdTable2 
 FOREIGN KEY (Table1_Id) 
 REFERENCES Table1 (Table1_Id) 
 ON UPDATE CASCADE 
 ON
1
Sudhir Bastakoti

merci S Doerin:

"Juste pour compléter ..." (50) dans une table Latin1 est différent de VARCHAR (50) dans une table UTF8. "

j'ai résolu ce problème en changeant le type des caractères de la table . la création a latin1 et le correct est utf8.

ajoute la ligne suivante . DEFAULT CHARACTER SET = utf8;

1

J'avais des problèmes pour utiliser Alter table pour ajouter une clé étrangère entre deux tables et ce qui m'a aidé à faire en sorte que chaque colonne à laquelle j'essayais d'ajouter une relation de clé étrangère était indexée. Pour ce faire, utilisez PHP myAdmin: Accédez au tableau, puis cliquez sur l'onglet Structure.

 enter image description here

Une fois que j'ai indexé les deux colonnes que je tentais de référencer avec mes clés étrangères, j'ai pu utiliser avec succès la table alter et créer la relation de clé étrangère. Vous verrez que les colonnes sont indexées comme dans la capture d'écran ci-dessous:

 enter image description here

remarquez comment Zip_code apparaît dans les deux tables. 

1
Chris Adams

Vérifiez le moteur des tables, les deux tables doivent être identiques, cela m'a beaucoup aidé.

1
mariobigboy

(Dernier renvoi) Même si le nom du champ et le type de données sont identiques mais que le classement n'est pas identique, le problème sera également résolu.

Par exemple

TBL NOM | LES DONNÉES TYPE | COLLATION

ActivityID | INT | latin1_general_ci ActivityID | INT | utf8_general_ci

Essayez de le changer en

TBL NOM | LES DONNÉES TYPE | COLLATION

ActivityID | INT | latin1_general_ci ActivityID | INT | latin1_general_ci

....

Cela a fonctionné pour moi.

1
Jimwel Anobong

J'ai eu le même problème avec Symfony 2.8.

Je ne l’ai pas compris au début, car il n’y avait pas de problème similaire avec la longueur des clés étrangères etc.

Enfin, je devais faire ce qui suit dans le dossier du projet. (Un redémarrage du serveur n'a pas aidé!)

app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-query app/console doctrine:cache:clear-result

1
rogaa

J'utilisais HeidiSQL et pour résoudre ce problème, je devais créer un index dans la table référencée avec toutes les colonnes référencées.

 adding index to table Heidisql

1
Doug

Vous devez vérifier que les deux sont identiques dans toutes leurs propriétés, inclus dans "Collation"

1
CrsCaballero

J'ai perdu des heures pour ça!

PK dans une table était utf8 dans une autre était utf8_unicode_ci!

1
LukaszTaraszka

Bien que les autres réponses soient très utiles, je voulais aussi partager mon expérience.

J'ai rencontré le problème lorsque j'avais supprimé une table dont id était déjà référencée comme clé étrangère dans d'autres tables ( avec data ) et j'ai essayé de recréer/importer la table avec quelques colonnes supplémentaires.

La requête de recréation (générée dans phpMyAdmin) ressemblait à ceci:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL,            /* No PRIMARY KEY index */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

... /* SOME DATA DUMP OPERATION */

ALTER TABLE `the_table`
  ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
  ADD UNIQUE KEY `uk_acu_donor_name` (`name`);

Comme vous le remarquerez peut-être, l'index PRIMARY KEY a été défini après la création ( et l'insertion de données ) à l'origine du problème.

Solution

La solution consistait à ajouter l'index PRIMARY KEY à la requête de définition de table pour la variable id à laquelle on faisait référence en tant que clé étrangère, tout en la supprimant de la partie ALTER TABLE où les index étaient définis:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL PRIMARY KEY,            /* <<== PRIMARY KEY INDEX ON CREATION */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1

J'ai eu les mêmes problèmes.

Le problème est que la colonne de référence n'est pas une clé primaire.

Faites-en une clé primaire et le problème est résolu.

1
longluffy

Vérifiez que vous avez spécifié le nom de la table dans le casse approprié (si les noms de table sont sensibles à la casse dans votre base de données). Dans mon cas je devais changer

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

à

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `CUSTOMER` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

notez que customer a été remplacé par CUSTOMER.

0
izogfif

J'ai eu le même problème avec la migration de Laravel 5.1 Schema Builder avec MariaDB 10.1.

Le problème était que j'avais saisi unigned au lieu de unsigned (la lettre s était manquante) lors de la définition de la colonne.

Après avoir corrigé l'erreur de frappe a été corrigé pour moi.

0
Arda

Même j’ai rencontré le même problème avec mysql et liquibase . Voici donc le problème: La table à partir de laquelle vous souhaitez référencer une colonne d'une autre table est différente en cas de type de données ou en termes de taille.

Error appears in below scenario:
Scenario 1:
Table A has column id, type=bigint
Table B column referenced_id type varchar(this column gets the value from the id column of Table A.)
Liquibase changeset for table B:

    <changeset id="XXXXXXXXXXX-1" author="xyz">
            <column name="referenced_id" **type="varchar"**>
        </column>
            </changeset>
    <changeSet id="XXXXXXXXXXX-2" author="xyz">
                <addForeignKeyConstraint constraintName="FK_table_A"
                    referencedTableName="A" **baseColumnNames="referenced_id**"
                    referencedColumnNames="id" baseTableName="B" />
    </changeSet>

Table A changeSet:

    <changeSet id="YYYYYYYYYY" author="xyz">
     <column **name="id"** **type="bigint"** autoIncrement="${autoIncrement}">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
    </changeSet>

Solution: 
correct the type of table B to bigint because the referenced table has type bigint.

Scenrario 2:
The type might be correct but the size might not.
e.g. :
Table B : referenced column type="varchar 50"
Table A : base column type ="varchar 255"

Solution change the size of referenced column to that of base table's column size.
0
ashish kathait

Vous pouvez également utiliser DBDesigner4, qui dispose d’une interface graphique pour créer votre base de données et les relier à l’aide de FK. Faites un clic droit sur votre table et sélectionnez "Copier la table SQL Créer" qui crée le code.

 enter image description here

0
TheHive

J'ai rencontré le même problème tout à l'heure. Dans mon cas, tout ce que je devais faire était de m'assurer que la table que je référence dans la clé étrangère devait être créée avant la table actuelle (plus tôt dans le code). Ainsi, si vous référencez une variable (x * 5), le système doit savoir ce que x est (x doit être déclaré dans les lignes de code précédentes). Cela a résolu mon problème, j'espère que cela aidera quelqu'un d'autre.

0