sql >> Databasteknik >  >> RDS >> Mysql

ER_FK_NO_INDEX_PARENT:Det gick inte att lägga till den främmande nyckeln. Saknar index för begränsning

Försök först analysera och förstå ditt schema. Jag ser ingen anledning till varför teamname bör vara en del av primärnyckeln. ID kolumnen är redan unik på grund av AUTO_INCREMENT alternativ. Så du kan bara göra den till primärnyckel.

Analysera nu begränsningarna för teamname . Om två lag inte kan ha samma namn, bör du definiera en UNIQUE KEY begränsning på teamname . Om varje lag måste ha ett namn, bör du definiera en NOT NULL begränsning på teamname . Med dessa begränsningar teams kan skapas som:

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

Nu kan du använda teamname kolumn för att identifiera en rad i teams tabell och kan använda den som främmande nyckel i andra tabeller. Din kod för players Tabellen ska nu fungera (se demo ).

Observera att en främmande nyckel vanligtvis refererar till en primärnyckel i en annan tabell. players Tabell skulle definieras som:

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

När du behöver veta lagnamnet på en spelare använder du ett JOIN:

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

Notera:Under de senaste dagarna har jag sett frågor med samma mönster om och om igen. Mönstret är:En främmande nyckel som refererar till en del av primärnyckeln i en annan tabell. Några exempel:

Kommentarer och svar föreslås för att definiera ett enkelt index på den refererade tabellen för att stödja FK-begränsningskontrollen. Gör inte det! Fundera på om du försöker lösa ditt problem genom att bara definiera ett index på teamname i teams tabell med:

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

MySQL accepterar det (se demo ). Men ditt schema tillåter två lag med samma namn. Förutsatt att du har två lag med namnet "apor". Och du har en spelare som har "apor" som lagnamn (FK). Vilket av de två lagen refereras till? Det kan du inte säga! Så du bör hålla dig till enkla regler. Och regeln för främmande nycklar är:Referera endast till fullständiga UNIKA eller PRIMÄRA NYCKLAR. Eller ännu enklare:Referera endast till fullständiga PRIMÄRNYCKLAR. Ett främmande nyckelvärde bör identifiera en specifik rad i den refererade tabellen.




  1. SQL - Hitta saknade int-värden i mestadels ordnade sekventiella serier

  2. Undantag för DBConcurrency uppstod vid uppdatering med dataadapter

  3. ModuleNotFoundError:Ingen modul med namnet 'mysql'

  4. Kan någon hjälpa till att förklara varför det är dåligt och fel att använda en SQL JOIN?