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

ER_FK_NO_INDEX_PARENT :Échec de l'ajout de la contrainte de clé étrangère. Index manquant pour la contrainte

Essayez d'abord d'analyser et de comprendre votre schéma. Je ne vois pas de raison, pourquoi teamname doit faire partie de la clé primaire. L'ID la colonne est déjà unique en raison du AUTO_INCREMENT option. Vous pouvez donc simplement en faire une clé primaire.

Analysez maintenant les contraintes sur teamname . Si deux équipes ne peuvent pas avoir le même nom, alors vous devez définir une UNIQUE KEY contrainte sur teamname . Si chaque équipe doit avoir un nom, alors vous devez définir un NOT NULL contrainte sur teamname . Avec ces contraintes les teams peut être créé comme :

CREATE TABLE IF NOT EXISTS teams (
  ID INT NOT NULL AUTO_INCREMENT,
  teamname VARCHAR(255) NOT NULL,
  PRIMARY KEY (ID),
  UNIQUE KEY (teamname )
);

Vous pouvez maintenant utiliser le teamname colonne pour identifier une ligne dans les teams table, et peut l'utiliser comme clé étrangère dans d'autres tables. Votre code pour les players la table devrait maintenant fonctionner (voir démo ).

Notez que généralement une clé étrangère fait référence à une clé primaire d'une autre table. Les players la table serait définie comme :

CREATE TABLE IF NOT EXISTS players (
  ID INT NOT NULL AUTO_INCREMENT,
  player_name VARCHAR(255),
  cm INT NOT NULL,
  team_id INT,
  PRIMARY KEY (ID),
  FOREIGN KEY (team_id) REFERENCES teams(ID)
);

Lorsque vous avez besoin de connaître le nom de l'équipe d'un joueur, vous utiliserez un JOIN :

SELECT p.*, t.teamname
FROM players p
LEFT JOIN teams t on t.ID = p.team_id

Remarque :ces derniers jours, j'ai vu des questions avec le même schéma encore et encore. Le modèle est :Une clé étrangère qui fait référence à une partie de la clé primaire dans une autre table. Quelques exemples :

Commentaires et réponses suggérés pour définir un index simple sur la table référencée pour prendre en charge la vérification de la contrainte FK. Ne fais pas ça ! Considérez si vous essayez de résoudre votre problème en définissant simplement un index sur teamname sur les teams tableau avec :

CREATE TABLE IF NOT EXISTS teams (
  ID INT NOT NULL AUTO_INCREMENT,
  teamname VARCHAR(255) NOT NULL,
  PRIMARY KEY (ID),
  INDEX (teamname )
);

MySQL acceptera cela (voir démo ). Mais votre schéma autorise deux équipes avec le même nom. En supposant que vous ayez deux équipes avec le nom "singes". Et vous avez un joueur qui a des "singes" comme nom d'équipe (FK). Laquelle des deux équipes est référencée ? Vous ne pouvez pas dire! Il vaut donc mieux s'en tenir à des règles simples. Et la règle pour les clés étrangères est la suivante :référencez uniquement les clés uniques ou primaires complètes. Ou encore plus simple :référencez uniquement les clés primaires complètes. Une valeur de clé étrangère doit identifier une ligne spécifique dans la table référencée.