Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL Création de tables avec des clés étrangères donnant errno :150

J'ai eu le même problème avec ALTER TABLE ADD FOREIGN KEY .

Au bout d'une heure, j'ai constaté que ces conditions devaient être satisfaites pour ne pas avoir l'erreur 150 :

  1. La table Parent doit exister avant que vous ne définissiez une clé étrangère pour la référencer. Vous devez définir les tables dans le bon ordre :la table parent d'abord, puis la table enfant. Si les deux tables se référencent, vous devez créer une table sans contraintes FK, puis créer la deuxième table, puis ajouter la contrainte FK à la première table avec ALTER TABLE .

  2. Les deux tables doivent toutes deux prendre en charge les contraintes de clé étrangère, c'est-à-dire ENGINE=InnoDB . Les autres moteurs de stockage ignorent silencieusement les définitions de clé étrangère, de sorte qu'ils ne renvoient aucune erreur ou avertissement, mais la contrainte FK n'est pas enregistrée.

  3. Les colonnes référencées dans la table Parent doivent être les colonnes les plus à gauche d'une clé. Idéal si la clé dans le parent est PRIMARY KEY ou UNIQUE KEY .

  4. La définition FK doit référencer la ou les colonnes PK dans le même ordre que la définition PK. Par exemple, si la clé REFERENCES Parent(a,b,c) alors le Parent's PK ne doit pas être défini sur les colonnes dans l'ordre (a,c,b) .

  5. La ou les colonnes PK de la table parent doivent être du même type de données que la ou les colonnes FK de la table enfant. Par exemple, si une colonne PK de la table Parent est UNSIGNED , assurez-vous de définir UNSIGNED pour la colonne correspondante dans le champ Table enfant.

    Exception :la longueur des chaînes peut être différente. Par exemple, VARCHAR(10) peut référencer VARCHAR(20) ou vice versa.

  6. Toute colonne FK de type chaîne doit avoir le même jeu de caractères et le même classement que la ou les colonnes PK correspondantes.

  7. S'il existe déjà des données dans la table enfant, chaque valeur de la ou des colonnes FK doit correspondre à une valeur de la ou des colonnes PK de la table parent. Vérifiez cela avec une requête comme :

    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    Cela doit renvoyer zéro (0) valeurs sans correspondance. Évidemment, cette requête est un exemple générique; vous devez substituer vos noms de table et vos noms de colonne.

  8. Ni la table Parent ni la table Child ne peuvent être TEMPORARY tableau.

  9. Ni la table parent ni la table enfant ne peuvent être PARTITIONED tableau.

  10. Si vous déclarez un FK avec le ON DELETE SET NULL option, alors la ou les colonnes FK doivent être nulles.

  11. Si vous déclarez un nom de contrainte pour une clé étrangère, le nom de la contrainte doit être unique dans tout le schéma, pas seulement dans la table dans laquelle la contrainte est définie. Deux tables ne peuvent pas avoir leur propre contrainte avec le même nom.

  12. S'il y a d'autres FK dans d'autres tables pointant vers le même champ pour lequel vous essayez de créer le nouveau FK, et qu'ils sont mal formés (c'est-à-dire un classement différent), ils devront d'abord être rendus cohérents. Cela peut être le résultat de modifications passées où SET FOREIGN_KEY_CHECKS = 0; a été utilisé avec une relation incohérente définie par erreur. Voir la réponse de @ andrewdotn ci-dessous pour savoir comment identifier ces problèmes FK.

J'espère que cela vous aidera.