Mysql
 sql >> Database >  >> RDS >> Mysql

ER_FK_NO_INDEX_PARENT:Impossibile aggiungere il vincolo di chiave esterna. Indice mancante per vincolo

Per prima cosa prova ad analizzare e comprendere il tuo schema. Non vedo un motivo, perché teamname dovrebbe essere parte della chiave primaria. Il ID la colonna è già univoca a causa di AUTO_INCREMENT opzione. Quindi puoi semplicemente renderlo chiave primaria.

Ora analizza i vincoli su teamname . Se due squadre non possono avere lo stesso nome, allora dovresti definire una UNIQUE KEY vincolo su teamname . Se ogni squadra deve avere un nome, allora dovresti definire un NOT NULL vincolo su teamname . Con questi vincoli i teams può essere creato come:

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

Ora puoi usare il teamname colonna per identificare una riga nei teams tabella e può usarlo come chiave esterna in altre tabelle. Il tuo codice per i players la tabella ora dovrebbe funzionare (vedi demo ).

Si noti che di solito una chiave esterna fa riferimento a una chiave primaria di un'altra tabella. I players la tabella sarebbe definita come:

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

Quando hai bisogno di conoscere il nome della squadra di un giocatore, dovresti usare un JOIN:

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

Nota:negli ultimi giorni ho visto domande con lo stesso schema ancora e ancora. Lo schema è:Una chiave esterna che fa riferimento a una parte della chiave primaria in un'altra tabella. Alcuni esempi:

Commenti e risposte hanno suggerito di definire un semplice indice sulla tabella di riferimento per supportare il controllo del vincolo FK. Non farlo! Considera se provi a risolvere il tuo problema semplicemente definendo un indice su teamname nei teams tabella 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 accetterà (vedi demo ). Ma il tuo schema consente due team con lo stesso nome. Supponendo che tu abbia due squadre con il nome "scimmie". E hai un giocatore che ha "scimmie" come nome della squadra (FK). Quale delle due squadre è referenziata? Non puoi dire! Quindi è meglio attenersi a regole semplici. E la regola per le chiavi esterne è:fare riferimento solo a CHIAVI UNICHE o PRIMARIE complete. O ancora più semplice:fare riferimento solo a CHIAVI PRIMARIE complete. Un valore di chiave esterna dovrebbe identificare una riga specifica nella tabella di riferimento.