Jeg havde det samme problem med ALTER TABLE ADD FOREIGN KEY
.
Efter en time fandt jeg ud af, at disse betingelser skal være opfyldt for ikke at få fejl 150:
-
Den overordnede tabel skal eksistere, før du definerer en fremmednøgle til at referere til den. Du skal definere tabellerne i den rigtige rækkefølge:Forældretabellen først, derefter Børnetabellen. Hvis begge tabeller refererer til hinanden, skal du oprette én tabel uden FK-begrænsninger, derefter oprette den anden tabel og derefter tilføje FK-begrænsningen til den første tabel med
ALTER TABLE
. -
De to tabeller skal begge understøtte fremmednøgle-begrænsninger, dvs.
ENGINE=InnoDB
. Andre lagringsmotorer ignorerer udenlandsk nøgledefinitioner, så de returnerer ingen fejl eller advarsler, men FK-begrænsningen gemmes ikke. -
De refererede kolonner i den overordnede tabel skal være kolonnerne længst til venstre i en nøgle. Bedst hvis nøglen i overordnet er
PRIMARY KEY
ellerUNIQUE KEY
. -
FK-definitionen skal referere til PK-kolonnen(r) i samme rækkefølge som PK-definitionen. For eksempel, hvis FK
REFERENCES Parent(a,b,c)
så må forældrenes PK ikke defineres på kolonner i rækkefølgen(a,c,b)
. -
PK-kolonnen(e) i overordnet-tabellen skal være den samme datatype som FK-kolonnen(-erne) i underordnet-tabellen. For eksempel, hvis en PK-kolonne i Overordnet-tabellen er
UNSIGNED
, sørg for at definereUNSIGNED
for den tilsvarende kolonne i feltet Undertabel.Undtagelse:længden af strenge kan være anderledes. For eksempel
VARCHAR(10)
kan henvise tilVARCHAR(20)
eller omvendt. -
Enhver FK-kolonne af strengtype skal have samme tegnsæt og sortering som den eller de tilsvarende PK-kolonner.
-
Hvis der allerede er data i Child-tabellen, skal hver værdi i FK-kolonnen(r) matche en værdi i Overordnet-tabellens PK-kolonne(r). Tjek dette med en forespørgsel som:
SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK WHERE Parent.PK IS NULL;
Dette skal returnere nul (0) umatchede værdier. Denne forespørgsel er naturligvis et generisk eksempel; du skal erstatte dine tabelnavne og kolonnenavne.
-
Hverken Overordnet-tabellen eller Underordnet-tabellen kan være en
MIDDELIGE tabel.
-
Hverken overordnet- eller underordnet-tabellen kan være en
PARTITIONED
tabel. -
Hvis du erklærer en FK med
ON DELETE SET NULL
mulighed, så skal FK-kolonnen(e) være nullable. -
Hvis du erklærer et begrænsningsnavn for en fremmednøgle, skal begrænsningsnavnet være unikt i hele skemaet, ikke kun i den tabel, hvori begrænsningen er defineret. To tabeller har muligvis ikke deres egen begrænsning med samme navn.
-
Hvis der er andre FK'er i andre tabeller, der peger på det samme felt, som du forsøger at oprette den nye FK for, og de er forkert udformet (dvs. forskellig sortering), skal de først gøres konsistente. Dette kan være et resultat af tidligere ændringer, hvor
SET FOREIGN_KEY_CHECKS =0;
blev brugt med et inkonsistent forhold defineret ved en fejl. Se @andrewdotns svar nedenfor for instruktioner om, hvordan du identificerer disse problem-FK'er.
Håber dette hjælper.