sql >> Base de Datos >  >> RDS >> Mysql

ER_FK_NO_INDEX_PARENT:no se pudo agregar la restricción de clave externa. Índice faltante para la restricción

Primero intente analizar y comprender su esquema. No veo una razón, por qué teamname debe ser parte de la clave principal. El ID la columna ya es única debido a AUTO_INCREMENT opción. Así que puedes convertirlo en clave principal.

Ahora analice las restricciones en teamname . Si dos equipos no pueden tener el mismo nombre, debe definir una UNIQUE KEY restricción en teamname . Si cada equipo debe tener un nombre, entonces debe definir un NOT NULL restricción en teamname . Con estas limitaciones, los teams se puede crear como:

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

Ahora puedes usar el teamname columna para identificar una fila en los teams tabla, y puede usarla como clave externa en otras tablas. Tu código para los players la tabla ahora debería funcionar (ver demostración ).

Tenga en cuenta que, por lo general, una clave externa hace referencia a una clave principal de otra tabla. Los players la tabla se definiría como:

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)
);

Cuando necesite saber el nombre del equipo de un jugador, usaría JOIN:

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

Nota:En los últimos días he visto preguntas con el mismo patrón una y otra vez. El patrón es:una clave externa que hace referencia a una parte de la clave principal en otra tabla. Algunos ejemplos:

Los comentarios y las respuestas sugirieron definir un índice simple en la tabla a la que se hace referencia para admitir la verificación de restricciones de FK. ¡No hagas eso! Considere si intenta solucionar su problema simplemente definiendo un índice en teamname en los teams mesa con:

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

MySQL lo aceptará (ver demostración ). Pero su esquema permite dos equipos con el mismo nombre. Asumiendo que tienes dos equipos con el nombre de "monos". Y tienes un jugador que tiene "monos" como nombre de equipo (FK). ¿A cuál de los dos equipos se hace referencia? ¡No puedes decir! Así que es mejor que te ciñas a reglas simples. Y la regla para las claves foráneas es:solo haga referencia a las CLAVES PRIMARIAS o ÚNICAS completas. O aún más simple:solo haga referencia a las CLAVES PRIMARIAS completas. Un valor de clave externa debe identificar una fila específica en la tabla a la que se hace referencia.