Jag hade samma problem med ALTER TABLE ADD FOREIGN KEY
.
Efter en timme upptäckte jag att dessa villkor måste vara uppfyllda för att inte få fel 150:
-
Den överordnade tabellen måste finnas innan du definierar en främmande nyckel för att referera till den. Du måste definiera tabellerna i rätt ordning:Föräldertabell först, sedan underordnad tabell. Om båda tabellerna refererar till varandra måste du skapa en tabell utan FK-begränsningar, skapa sedan den andra tabellen och lägg sedan till FK-begränsningen till den första tabellen med
ALTER TABLE
. -
De två tabellerna måste båda stödja begränsningar för främmande nyckel, dvs.
ENGINE=InnoDB
. Andra lagringsmotorer ignorerar tyst definitioner av främmande nyckel, så de returnerar inget fel eller varning, men FK-begränsningen sparas inte. -
De refererade kolumnerna i den överordnade tabellen måste vara kolumnerna längst till vänster i en nyckel. Bäst om nyckeln i den överordnade är
PRIMARY KEY
ellerUNIQUE KEY
. -
FK-definitionen måste referera till PK-kolumn(erna) i samma ordning som PK-definitionen. Till exempel, om FK
REFERENSER Förälder(a,b,c)
då får inte förälderns PK definieras i kolumner i ordning(a,c,b)
. -
PK-kolumn(erna) i överordnade tabellen måste vara samma datatyp som FK-kolumn(erna) i tabellen underordnade. Till exempel, om en PK-kolumn i överordnade tabellen är
UNSIGNED
, se till att definieraUNSIGNED
för motsvarande kolumn i fältet Underordnade tabell.Undantag:längden på strängarna kan vara olika. Till exempel,
VARCHAR(10)
kan referera tillVARCHAR(20)
eller vice versa. -
Alla FK-kolumner av strängtyp måste ha samma teckenuppsättning och sortering som motsvarande PK-kolumner.
-
Om det redan finns data i Child-tabellen, måste varje värde i FK-kolumn(erna) matcha ett värde i Parent-tabellens PK-kolumn(er). Kontrollera detta med en fråga som:
SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK WHERE Parent.PK IS NULL;
Detta måste returnera noll (0) omatchade värden. Uppenbarligen är denna fråga ett allmänt exempel; du måste byta ut dina tabellnamn och kolumnnamn.
-
Varken den överordnade tabellen eller den underordnade tabellen kan vara en
TILLfällig bord.
-
Varken den överordnade tabellen eller den underordnade tabellen kan vara en
PARTITIONED
bord. -
Om du deklarerar en FK med
ON DELETE SET NULL
alternativet, då måste FK-kolumnen/kolumnerna vara nullbara. -
Om du deklarerar ett begränsningsnamn för en främmande nyckel måste begränsningsnamnet vara unikt i hela schemat, inte bara i tabellen där begränsningen är definierad. Två tabeller kanske inte har sina egna begränsningar med samma namn.
-
Om det finns några andra FK:er i andra tabeller som pekar på samma fält som du försöker skapa den nya FK för, och de är felaktiga (dvs. olika sortering), måste de göras konsekventa först. Detta kan vara ett resultat av tidigare ändringar där
SET FOREIGN_KEY_CHECKS =0;
användes med ett inkonsekvent förhållande definierat av misstag. Se @andrewdotns svar nedan för instruktioner om hur man identifierar dessa problem-FK:er.
Hoppas detta hjälper.