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:
- vad är problemet med mina tabeller i mysql?
- Felkod :1822. Det gick inte att lägga till den främmande nyckelbegränsningen
- #1005 (errno) :150 "Främmande nyckelbegränsning är felaktigt utformad")
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.