sql >> Databáze >  >> RDS >> Mysql

MySQL Vytváření tabulek s cizími klíči dává errno:150

Měl jsem stejný problém s ALTER TABLE ADD FOREIGN KEY .

Po hodině jsem zjistil, že tyto podmínky musí být splněny, aby se neobjevila chyba 150:

  1. Nadřazená tabulka musí existovat předtím, než definujete cizí klíč, abyste na ni odkazovali. Tabulky musíte definovat ve správném pořadí:Nejprve nadřazená tabulka, potom podřízená tabulka. Pokud na sebe obě tabulky odkazují, musíte vytvořit jednu tabulku bez omezení FK, poté vytvořit druhou tabulku a poté přidat omezení FK do první tabulky pomocí ALTER TABLE .

  2. Obě tabulky musí podporovat omezení cizího klíče, tj. ENGINE=InnoDB . Jiné úložné stroje tiše ignorují definice cizích klíčů, takže nevrací žádnou chybu ani varování, ale omezení FK se neuloží.

  3. Odkazované sloupce v nadřazené tabulce musí být sloupce klíče zcela vlevo. Nejlepší je, když je klíč v Parentu PRIMARY KEY nebo UNIQUE KEY .

  4. Definice FK musí odkazovat na sloupec (sloupce) PK ve stejném pořadí jako definice PK. Například pokud FK REFERENCES Parent(a,b,c) pak rodičovská PK nesmí být definována ve sloupcích v pořadí (a,c,b) .

  5. Sloupce PK v nadřazené tabulce musí mít stejný datový typ jako sloupce FK v podřízené tabulce. Pokud je například sloupec PK v nadřazené tabulce UNSIGNED , nezapomeňte definovat UNSIGNED pro odpovídající sloupec v poli Child table.

    Výjimka:délka řetězců se může lišit. Například VARCHAR(10) může odkazovat na VARCHAR(20) nebo naopak.

  6. Všechny sloupce FK typu řetězce musí mít stejnou znakovou sadu a řazení jako odpovídající sloupce PK.

  7. Pokud již v podřízené tabulce jsou data, musí se každá hodnota ve sloupci FK shodovat s hodnotou ve sloupci PK nadřazené tabulky. Zkontrolujte to pomocí dotazu jako:

    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    To musí vrátit nulové (0) neshodné hodnoty. Je zřejmé, že tento dotaz je obecný příklad; musíte nahradit názvy tabulek a názvy sloupců.

  8. Nadřazená ani podřízená tabulka nemohou být TEMPORARY tabulka.

  9. Nadřazená ani podřízená tabulka nemohou být PARTITIONED tabulka.

  10. Pokud deklarujete FK pomocí ON DELETE SET NULL pak musí mít sloupce FK hodnotu null.

  11. Pokud deklarujete název omezení pro cizí klíč, musí být název omezení jedinečný v celém schématu, nejen v tabulce, ve které je omezení definováno. Dvě tabulky nemusí mít vlastní omezení se stejným názvem.

  12. Pokud jsou v jiných tabulkách nějaké další FK ukazující na stejné pole, pro které se pokoušíte vytvořit nový FK, a mají nesprávný formát (tj. jiné řazení), bude nutné je nejprve uvést do souladu. Může to být důsledek minulých změn, kde SET FOREIGN_KEY_CHECKS = 0; byl použit s nekonzistentním vztahem definovaným omylem. Viz odpověď @andrewdotn níže pro pokyny, jak identifikovat tyto problémové FK.

Doufám, že to pomůže.



  1. Vytvořte zobrazení v SQL Server 2017

  2. MySQL odstraňuje nenumerické znaky pro porovnání

  3. Použití Pythonu a MySQL v procesu ETL:SQLAlchemy

  4. 4 způsoby, jak vypsat všechny tabulky v databázi MariaDB