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

MySQL Oprettelse af tabeller med fremmednøgler giver fejlnr.:150

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:

  1. 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 .

  2. 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.

  3. 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 eller UNIQUE KEY .

  4. 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) .

  5. 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 definere UNSIGNED for den tilsvarende kolonne i feltet Undertabel.

    Undtagelse:længden af ​​strenge kan være anderledes. For eksempel VARCHAR(10) kan henvise til VARCHAR(20) eller omvendt.

  6. Enhver FK-kolonne af strengtype skal have samme tegnsæt og sortering som den eller de tilsvarende PK-kolonner.

  7. 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.

  8. Hverken Overordnet-tabellen eller Underordnet-tabellen kan være en MIDDELIGE tabel.

  9. Hverken overordnet- eller underordnet-tabellen kan være en PARTITIONED tabel.

  10. Hvis du erklærer en FK med ON DELETE SET NULL mulighed, så skal FK-kolonnen(e) være nullable.

  11. 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.

  12. 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.



  1. Sådan bruger du analytiske funktioner i Oracle (Overpartition efter søgeord)

  2. Oracle RAC N+1 Redundans

  3. Find indeks over sidste forekomst af en understreng ved hjælp af T-SQL

  4. Asynkron replikering automatisk failover i MySQL 8.0.22