Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL erstellt Tabellen mit Fremdschlüsseln mit Fehlernummer:150

Ich hatte das gleiche Problem mit ALTER TABLE ADD FOREIGN KEY .

Nach einer Stunde stellte ich fest, dass diese Bedingungen erfüllt sein müssen, um den Fehler 150 nicht zu erhalten:

  1. Die übergeordnete Tabelle muss vorhanden sein, bevor Sie einen Fremdschlüssel definieren, um darauf zu verweisen. Sie müssen die Tabellen in der richtigen Reihenfolge definieren:zuerst die übergeordnete Tabelle, dann die untergeordnete Tabelle. Wenn beide Tabellen aufeinander verweisen, müssen Sie eine Tabelle ohne FK-Einschränkungen erstellen, dann die zweite Tabelle erstellen und dann die FK-Einschränkung mit ALTER TABLE zur ersten Tabelle hinzufügen .

  2. Die beiden Tabellen müssen beide Fremdschlüsseleinschränkungen unterstützen, d. h. ENGINE=InnoDB . Andere Speicher-Engines ignorieren Fremdschlüsseldefinitionen stillschweigend, sodass sie keinen Fehler oder keine Warnung zurückgeben, aber die FK-Einschränkung wird nicht gespeichert.

  3. Die referenzierten Spalten in der übergeordneten Tabelle müssen die Spalten ganz links eines Schlüssels sein. Am besten, wenn der Schlüssel im Parent PRIMARY KEY ist oder UNIQUE KEY .

  4. Die FK-Definition muss die PK-Spalte(n) in derselben Reihenfolge wie die PK-Definition referenzieren. Wenn beispielsweise der FK REFERENCES Parent(a,b,c) dann darf der PK des Elternteils nicht für Spalten in der Reihenfolge (a,c,b) definiert werden .

  5. Die PK-Spalte(n) in der übergeordneten Tabelle müssen denselben Datentyp wie die FK-Spalte(n) in der untergeordneten Tabelle haben. Beispiel:Eine PK-Spalte in der übergeordneten Tabelle ist UNSIGNED , achten Sie darauf, UNSIGNED zu definieren für die entsprechende Spalte im Feld Child-Tabelle.

    Ausnahme:Länge der Strings kann unterschiedlich sein. Beispiel:VARCHAR(10) kann auf VARCHAR(20) verweisen oder umgekehrt.

  6. Alle FK-Spalten vom Typ Zeichenfolge müssen denselben Zeichensatz und dieselbe Sortierung wie die entsprechende(n) PK-Spalte(n) haben.

  7. Wenn bereits Daten in der untergeordneten Tabelle vorhanden sind, muss jeder Wert in der/den FK-Spalte(n) mit einem Wert in der/den PK-Spalte(n) der übergeordneten Tabelle übereinstimmen. Überprüfen Sie dies mit einer Abfrage wie:

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

    Dies muss null (0) nicht übereinstimmende Werte zurückgeben. Offensichtlich ist diese Abfrage ein allgemeines Beispiel; Sie müssen Ihre Tabellennamen und Spaltennamen ersetzen.

  8. Weder die übergeordnete Tabelle noch die untergeordnete Tabelle können ein TEMPORARY sein Tabelle.

  9. Weder die übergeordnete Tabelle noch die untergeordnete Tabelle können PARTITIONED sein Tabelle.

  10. Wenn Sie einen FK mit dem ON DELETE SET NULL deklarieren Option, dann muss/müssen die FK-Spalte(n) nullable sein.

  11. Wenn Sie einen Constraint-Namen für einen Fremdschlüssel deklarieren, muss der Constraint-Name im gesamten Schema eindeutig sein, nicht nur in der Tabelle, in der der Constraint definiert ist. Zwei Tabellen dürfen keine eigene Einschränkung mit demselben Namen haben.

  12. Wenn es andere FKs in anderen Tabellen gibt, die auf dasselbe Feld zeigen, für das Sie versuchen, das neue FK zu erstellen, und sie fehlerhaft sind (d. h. unterschiedliche Sortierung), müssen sie zuerst konsistent gemacht werden. Dies kann auf frühere Änderungen zurückzuführen sein, bei denen SET FOREIGN_KEY_CHECKS = 0; wurde mit einer irrtümlich definierten inkonsistenten Beziehung verwendet. In der Antwort von @andrewdotn unten finden Sie Anweisungen zum Identifizieren dieser problematischen FKs.

Hoffe das hilft.