MySQL: Tabelle kann nicht erstellt werden (errno: 150)

156

Ich versuche, eine SQL-Datei zu importieren, und sie schlägt beim Erstellen von Tabellen fehl.

Hier ist die Abfrage, die fehlschlägt:

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

Ich habe die .sql aus derselben Datenbank exportiert, alle Tabellen gelöscht und jetzt versuche ich, sie zu importieren. Warum schlägt sie fehl?

MySQL: Tabelle './dbname/data.frm' kann nicht erstellt werden (errno: 150)

gtilx
quelle
1
Für im Wesentlichen alle Ursachen dieses Fehlers finden Sie hier eine umfassende Ressource für die Ursachen von Fehler Nr. 150 (und Fehler Nr. 121 / anderen Fremdschlüsselfehlern) in MySQL.
John Smith
21
Ich habe festgestellt, dass die Spalten identisch sein müssen (auch das vorzeichenlose Flag muss übereinstimmen).
Justin Skiles
3
@ JohnSmith ... wo?
Charles Wood
3
Ich schlage vor, diesen Blog-Beitrag zu lesen, in dem 10 mögliche Ursachen aufgeführt sind: verysimple.com/2006/10/22/…
Mark Amery
@ CharlesWood: " John Smith ... gesehen 6. April 13 um 19:29 ", das ist etwa drei Monate vor Ihrem Kommentar. Ich habe die Befürchtung, dass ein Geheimnis des "Wo" erst am Ende dieser trüben Welt gelüftet wird! :>
Trejder

Antworten:

167

Aus der MySQL - FOREIGN KEY Constraints-Dokumentation :

Wenn Sie eine Tabelle neu erstellen, die gelöscht wurde, muss sie eine Definition haben, die den Fremdschlüsseleinschränkungen entspricht, auf die sie verweist. Es muss die richtigen Spaltennamen und -typen haben und Indizes für die Schlüssel, auf die verwiesen wird, wie bereits erwähnt. Wenn diese nicht erfüllt sind, gibt MySQL Fehler 1005 zurück und verweist in der Fehlermeldung auf Fehler 150, was bedeutet, dass eine Fremdschlüsseleinschränkung nicht korrekt gebildet wurde. Wenn eine ALTER TABLE aufgrund von Fehler 150 fehlschlägt, bedeutet dies in ähnlicher Weise, dass eine Fremdschlüsseldefinition für die geänderte Tabelle falsch gebildet wird.

OMG Ponys
quelle
1
Können zwei Spalten aus einer Tabelle auf eine Spalte aus einer anderen Tabelle verweisen, in der es sich um PK handelt?
Eugene
1
@Eugene: Jede der beiden Spalten kann eine Fremdschlüsselbeziehung zur PK in einer anderen Tabelle haben - nicht beide Spalten als einzelne Fremdschlüsselbeziehung.
OMG Ponys
1
@OMGPonies: Danke, dass du diese Frage beantwortet hast! .. Ich habe danach gesucht ... Ich habe auch hier eine Frage gestellt stackoverflow.com/questions/13487010/… .... Obwohl ich einige gute Antworten habe, aber ich möchte konform sein Whether its possible to write Nested Query for my problem? ..Ich würde Sie bitten, mir auch zu antworten!
Grijesh Chauhan
19
Mein Fehler war, dass die Mastertabelle MyISAM und die InnoDB-Engine der untergeordneten Tabelle hatte. Das aktuelle Skript create.sql verwendete InnoDB für alle Tabellen, aber ich hatte eine sehr sehr alte Installation, in der das erste Skript MyISAM verwendete.
Wen
2
@Whome - Ja, hier ist das gleiche Problem aufgetreten.
Aroth
96

Fehler 150 bedeutet, dass Sie ein Problem mit Ihrem Fremdschlüssel haben. Möglicherweise ist der Schlüssel auf dem Fremdtisch nicht genau der gleiche Typ?

Dan McGrath
quelle
15
Danke :) für mich, die Datentypen sind INT, aber einer ohne Vorzeichen, der andere nicht
Anh Nguyen
6
Bei der Verwendung von Schema-Generatoren stoße ich häufig auf BIGINTvs. INT
Xeoncross
Ich bin auf dasselbe Problem gestoßen, wenn der Fremdschlüssel kein INT-Wert ist. Die Spalte muss EINZIGARTIG sein, wenn sich der Fremdschlüssel darauf bezieht.
PhatHV
62

Sie können die eigentliche Fehlermeldung erhalten, indem Sie ausführen SHOW ENGINE INNODB STATUS;und dann LATEST FOREIGN KEY ERRORin der Ausgabe suchen .

Quelle: Antwort eines anderen Benutzers in einer ähnlichen Frage

Denilson Sá Maia
quelle
7
Das ist eigentlich sehr nützlich. Es zeigt Ihnen den genauen Fehler.
Csongor Fagyal
Vielen Dank. Schade, dass MySQL Workbench davon keinen Gebrauch macht.
Scipilot
Genial. Das ist so hilfreich. Zeigt Ihnen den genauen Fehler an. Meins war, die Spalte NULLABLE gemacht zu haben, aber "on delete set null" gesetzt zu haben. Ich danke dir sehr.
Abhishek Saini
Wenn Sie Berechtigungen auf Ihrem Server haben :(
Christopher Smit
30

Datentypen müssen genau übereinstimmen. Wenn Sie mit Varchar-Typen arbeiten, müssen die Tabellen dieselbe Sortierung verwenden.

Esben Skov Pedersen
quelle
4
Danke für das Sortierbit.
Arahant
25

Ich denke, all diese richtigen Antworten führen die Frage in die Irre.

Die eigentliche Antwort lautet: Bevor Sie eine Wiederherstellung starten, wenn Sie eine Speicherauszugsdatei mit Fremdschlüsseln wiederherstellen:

SET FOREIGN_KEY_CHECKS=0;

da die Wiederherstellung natürlich einige Einschränkungen erzeugt, bevor die fremde Tabelle überhaupt existiert.

Colin
quelle
Dies zu tun hat bei mir nicht funktioniert, gibt immer noch den Fehler. Irgendwelche Ideen?
Joseph Astrahan
24

In einigen Fällen kann diese Fehlermeldung auftreten, wenn zwischen den zugehörigen Tabellen unterschiedliche Engines vorhanden sind. Beispielsweise kann eine Tabelle InnoDB verwenden, während die andere MyISAM verwendet. Beide müssen gleich sein

Pi.
quelle
Danke - das war mein Problem.
Scipilot
Das war mein Problem. Danke
thed0ctor
Dies kann passieren, wenn Sie mit mysqldump eine SQL-Datei der innodb-Tabelle erstellt haben und diese stattdessen als myisam talbes exportiert wurden.
Amado Martinez
11

Fehler Nr. 150 bedeutet einen Fehler bei der Fremdschlüsseleinschränkung. Sie erstellen diese Tabelle wahrscheinlich vor der Tabelle, von der der Fremdschlüssel abhängt (Tabelle keywords). Erstellen Sie diese Tabelle zuerst und es sollte gut funktionieren.

Wenn dies nicht der Fall ist, entfernen Sie die Fremdschlüsselanweisung und fügen Sie sie hinzu, nachdem die Tabelle erstellt wurde. Sie erhalten eine aussagekräftigere Fehlermeldung über den spezifischen Einschränkungsfehler.

Eran Galperin
quelle
10

Es gibt einige Dinge, die Errno 150 verursachen können. Für Leute, die dieses Thema suchen, ist hier eine meiner Meinung nach nahezu vollständige Liste (Quelle Ursachen von Errno 150 ):

Für errno 150 oder errno 121, indem Sie einfach SHOW ENGINE INNODB STATUS eingeben, gibt es einen Abschnitt namens "LATEST FOREIGN KEY ERROR". Darunter erhalten Sie eine sehr hilfreiche Fehlermeldung, die Ihnen in der Regel sofort mitteilt, worum es geht. Sie benötigen SUPER-Berechtigungen, um es auszuführen. Wenn Sie diese nicht haben, müssen Sie nur die folgenden Szenarien testen.

1) Datentypen stimmen nicht überein: Die Spaltentypen müssen identisch sein

2) Übergeordnete Spalten nicht indiziert (oder in falscher Reihenfolge indiziert)

3) Spaltenkollatierungen stimmen nicht überein

4) Verwenden von SET NULL für eine NOT NULL-Spalte

5) Tabellenkollatierungen stimmen nicht überein: Selbst wenn die Spaltenkollatierungen übereinstimmen, kann dies bei einigen MySQL-Versionen ein Problem sein.

6) Die übergeordnete Spalte ist in der übergeordneten Tabelle nicht vorhanden. Überprüfen Sie die Rechtschreibung (und möglicherweise ein Leerzeichen am Anfang oder Ende der Spalte).

7) Einer der Indizes für eine der Spalten ist unvollständig oder die Spalte ist zu lang für einen vollständigen Index. Beachten Sie, dass MySQL (sofern Sie es nicht optimieren) eine maximale Schlüssellänge für eine Spalte von 767 Byte hat (dies entspricht einer varchar (255) UTF-Spalte).

Falls Sie eine Errno 121 erhalten, gibt es einige Ursachen:

1) Der von Ihnen gewählte Einschränkungsname ist bereits vergeben

2) Auf einigen Systemen, wenn bei Ihren Anweisungs- und Tabellennamen ein Fallunterschied besteht. Dies kann Sie beißen, wenn Sie von einem Server zu einem anderen wechseln, für den unterschiedliche Regeln für die Fallbearbeitung gelten.

Juacala
quelle
In einigen Versionen erhalten Sie eine Errno 150, wenn die Tabelle nicht innodb ist, in einigen Versionen schlägt sie jedoch nur stillschweigend fehl.
Juacala
Danke, das war großartig: | ------------------------ | NEUESTER AUSLÄNDISCHER SCHLÜSSELFEHLER | ------------------------ | Sie haben eine SET NULL-Bedingung definiert, obwohl einige der | Spalten sind als NOT NULL definiert.
Sam Critchley
8

Manchmal ist MySQL einfach nur super dumm - ich kann den Grund für Fremdschlüssel verstehen. Aber in meinem Fall habe ich gerade die gesamte Datenbank gelöscht und erhalte immer noch den Fehler. Warum? Ich meine, es gibt keine Datenbank mehr ... und der SQL-Benutzer, den ich benutze, hat keinen Zugriff auf andere Datenbanken auf dem Server ... Ich meine, der Server ist für den aktuellen Benutzer "leer" und ich bekomme immer noch dieser Fehler? Tut mir leid, aber ich denke, MySQL lügt mich an ... aber ich kann damit umgehen :) Fügen Sie einfach diese beiden Zeilen SQL um Ihre verdammte Aussage hinzu:

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

Jetzt sollte die SQL ausgeführt werden ... Wenn Sie wirklich ein Fremdschlüsselproblem haben, wird es Ihnen in der Zeile angezeigt, in der Sie die Überprüfungen wieder aktivieren - dies wird dann fehlschlagen ... aber mein Server ist nur leise :)

jebbie
quelle
Dies kann zu Problemen führen, wenn tatsächlich Unterschiede zwischen der Spalte und der Spalte bestehen, auf die verwiesen wird. Zum Beispiel. Angenommen, die Spalte, auf die verwiesen wird, ist ein Varchar (200) und der Verweiser ist Varchar (50). Wenn eine Kaskade versucht wird, kann dies zu einem seltsamen Verhalten führen. Ich bin nicht auf ein Problem gestoßen, bei dem errno 150 aufgrund einer Dateninkongruenz ausgegeben wird.
Juacala
Interessante Einsicht @juacala :) Lustig für mich ist nur, wenn ich darauf stieß, mein Ansatz hat es immer behoben ... zumindest bis heute: D Aber wir hören nie auf zu lernen, richtig;)
jebbie
Dies half mir tatsächlich bei der Erstellung einer Skript-Liquibase. Das Skript lief einwandfrei unter MySQL> 5.5, schlug jedoch für Version 5.1 fehl.
Delbertooo
4

Nachdem Sie die obigen Antworten durchgearbeitet und ein wenig experimentiert haben, ist dies ein effektiver Weg, um Fremdschlüsselfehler in MySQL zu lösen (1005 - Fehler 150).

Damit der Fremdschlüssel ordnungsgemäß erstellt werden kann, muss MySQL lediglich Folgendes tun:

  • Alle referenzierten Schlüssel MÜSSEN entweder den PRIMARY- oder den UNIQUE-Index haben.
  • Die Referenzierungsspalte muss erneut den gleichen Datentyp wie die Referenzierungsspalte haben.

Erfüllen Sie diese Anforderungen und alles wird gut.

Davies Malesi
quelle
4

Ich habe diesen Fehler festgestellt, als ich die Windows-Anwendung auf Linux portiert habe. In Windows wird bei Namen von Datenbanktabellen nicht zwischen Groß- und Kleinschreibung unterschieden, und unter Linux wird zwischen Groß- und Kleinschreibung unterschieden, wahrscheinlich aufgrund von Unterschieden im Dateisystem. Also, auf Windows-Tabelle Table1ist das gleiche wie table1und in REFERENCESbeiden table1und Table1funktioniert. Unter Linux wurde bei der Verwendung der Anwendung table1anstelle der Table1Datenbankstruktur der Fehler # 150 angezeigt. Als ich in Table1Referenzen korrekte Groß- und Kleinschreibung machte , funktionierte es auch unter Linux. Wenn nichts anderes hilft, stellen Sie sicher, dass REFERENCESSie unter Linux die richtige Groß- und Kleinschreibung im Tabellennamen verwenden.

Vitalii
quelle
Das war auch mein Fall! Verschieben des Skripts von einer Groß- und Kleinschreibung (OS X) in eine MySQL-Version (Debian) ohne Berücksichtigung der Groß- und Kleinschreibung.
mircealungu
3

Ändern Sie die Engines Ihrer Tabellen, nur innoDB unterstützt Fremdschlüssel

Lappies
quelle
3

Wenn die PK-Tabelle in einem CHARSET erstellt wird und Sie dann eine FK-Tabelle in einem anderen CHARSET erstellen. Dann wird möglicherweise auch dieser Fehler angezeigt. Auch ich habe diesen Fehler erhalten, aber nachdem der Zeichensatz in PK-Zeichensatz geändert wurde, wurde er fehlerfrei ausgeführt

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;
Tinku
quelle
3

Dieser Fehler kann auftreten, wenn zwei Tabellen eine Referenz haben, z. B. eine Tabelle Student und eine andere Tabelle Education, und wir möchten, dass die Education-Tabelle eine Fremdschlüsselreferenz der Student-Tabelle enthält. In diesem Fall sollte der Spaltendatentyp für beide Tabellen gleich sein, da sonst ein Fehler generiert wird.

Manzarul Haque
quelle
3

In den meisten Fällen liegt das Problem an der ENGINE-Differenz. Wenn das übergeordnete Element von InnoDB erstellt wird, sollten die referenzierten Tabellen von MyISAM erstellt werden und umgekehrt

Sunil Kumar Mohanty
quelle
3

In meinem Fall. Ich hatte Probleme mit der Engine und dem Zeichensatz, weil mein Hosting-Server die Einstellungen änderte und meine neuen Tabellen MyISAM waren, meine alten Tabellen jedoch InnoDB sind. Ich habe mich nur verändert.

Ignacio Hernández
quelle
Das war richtig für mich, weil ich eine Datenbank geändert habe, die nicht von mir erstellt wurde.
FonzTech
3

Normalerweise verursacht die Nichtübereinstimmung zwischen Fremdschlüssel und Primärschlüssel den Fehler: 150.

Der Fremdschlüssel muss denselben Datentyp wie der Primärschlüssel haben . Auch wenn der Primärschlüssel ist unsigned dann der Fremdschlüssel muss auch sein , ohne Vorzeichen .

Rakesh
quelle
3

Ich hatte das gleiche Problem. Es bezog sich auf die Tabellenspalte Kollatierung und Zeichensatz . Stellen Sie sicher, dass Zeichensatz und Sortierung für beide Spalten in zwei Tabellen identisch sind. Wenn Sie einen Fremdschlüssel festlegen möchten. Beispiel: Wenn Sie einen Fremdschlüssel in die Spalte userID der Tabelle userImage einfügen, die auf die Spalte userID der Tabelle users verweist. Die Sortierung muss dann für beide Tabellenspalten mit utf8_general_ci und dem Zeichensatz utf8 identisch sein . Wenn Sie eine Tabelle erstellen, übernimmt mysql im Allgemeinen diese beiden Konfigurationen aus den Servereinstellungen.

Sushilkumar
quelle
Warum habe ich diesen Poist noch nie gesehen? Ich verbrachte eine Stunde damit, die Grundursache herauszufinden. Es war der Zeichensatz in meinem Fall. Referenzierte und referenzierende Tabellen müssen denselben Zeichensatz haben.
Sujit Joshi
2

Stellen Sie sicher, dass sowohl Ihre Primärschlüsselspalte als auch die referenzierte Spalte dieselben Datentypen und Attribute haben (vorzeichenlose, binäre, vorzeichenlose Nullfüllung usw.).

Basit
quelle
2

In einem echten Randfall haben Sie ein MySQL-Tool (in meinem Fall Sequel Pro) verwendet, um eine Datenbank umzubenennen. Dann erstellte eine Datenbank mit dem gleichen Namen.

Dadurch wurden Fremdschlüsseleinschränkungen auf denselben Datenbanknamen beschränkt, sodass die umbenannte Datenbank (z. B. my_db_renamed) Fremdschlüsseleinschränkungen in der neu erstellten Datenbank (my_db) aufwies.

Ich bin mir nicht sicher, ob dies ein Fehler in Sequel Pro ist oder ob ein Anwendungsfall dieses Verhalten erfordert, aber es hat mich den größten Teil eines Morgens gekostet: /

chim
quelle
2

Ich hatte den gleichen Fehler. In meinem Fall war der Grund für den Fehler, dass ich eine ON DELETE SET NULL-Anweisung in der Einschränkung hatte, während das Feld, für das ich die Einschränkung in ihre Definition eingefügt habe, eine NOT NULL-Anweisung hatte. Das Zulassen von NULL im Feld löste das Problem.

Wilbert van Diemen
quelle
2

Ich habe diese Art von Problem beim Erstellen der Datenbank aus der Textdatei festgestellt.

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

Ich habe gerade die obigen Zeilen geschrieben Create.bat und die Fledermausdatei ausgeführt.

Mein Fehler liegt in der Reihenfolge der Ausführung in meinen SQL-Dateien. Ich habe versucht, eine Tabelle mit Primärschlüssel und auch Fremdschlüssel zu erstellen. Während der Ausführung wird nach der Referenztabelle gesucht, Tabellen sind jedoch nicht vorhanden. Es wird also diese Art von Fehler zurückgeben.

Wenn Sie Tabellen mit Fremdschlüssel erstellen, überprüfen Sie, ob die Referenztabellen vorhanden waren oder nicht. Überprüfen Sie auch den Namen der Referenztabellen und -felder.

Dharani Dharan
quelle
Mit anderen Worten, Sie haben versucht, eine Tabelle mit einem Fremdschlüssel zu erstellen, der auf eine andere Tabelle verweist, die noch nicht vorhanden war. Erstellen Sie die Tabellen in der richtigen Reihenfolge, um das Problem zu lösen.
Vincent
2

Ich hatte ein ähnliches Problem, aber mein Problem war, dass ich einer vorhandenen Tabelle mit Daten ein neues Feld hinzufügte und das neue Feld auf ein anderes Feld aus der übergeordneten Tabelle verwies und außerdem die Definition NOT NULL und ohne STANDARDWERTE hatte. - Ich fand heraus, warum die Dinge nicht funktionierten, weil

  1. Mein neues Feld musste die leeren Felder automatisch mit einem Wert aus der übergeordneten Tabelle in jedem Datensatz füllen, bevor die Einschränkung angewendet werden konnte. Jedes Mal, wenn die Einschränkung angewendet wird, muss die Integrität der Tabellendaten intakt bleiben. Das Implementieren der Einschränkung (Fremdschlüssel), jedoch gab es einige Datenbankeinträge, die nicht die Werte aus der übergeordneten Tabelle enthielten, würde bedeuten, dass die Daten beschädigt sind, sodass MySQL Ihre Einschränkung niemals durchsetzen würde

Es ist wichtig zu bedenken, dass unter normalen Umständen, wenn Sie Ihre Datenbank frühzeitig geplant und Einschränkungen vor dem Einfügen von Daten implementiert haben, dieses spezielle Szenario vermieden wird

Der einfachere Ansatz, um dieses Problem zu vermeiden, ist zu

  • Speichern Sie die Daten Ihrer Datenbanktabellen
  • Schneiden Sie die Tabellendaten (und Tabellenartefakte, z. B. Indizes usw.) ab.
  • Wenden Sie die Einschränkungen an
  • Importieren Sie Ihre Daten

Ich hoffe das hilft jemandem

Chitwarnold
quelle
1

Vielleicht dies wird dazu beitragen? Die Definition der Primärschlüsselspalte sollte genau mit der Fremdschlüsselspalte übereinstimmen.

Mukus
quelle
1

Stellen Sie sicher, dass alle Tabellen Fremdschlüssel unterstützen - InnoDB-Engine

joksy82
quelle
1

Die Spalte der PARENT-Tabelle, auf die Sie sich aus der untergeordneten Tabelle beziehen, muss eindeutig sein. Ist dies nicht der Fall, verursachen Sie einen Fehler Nr. 150.

Dila Ram Gurung
quelle
Es wäre wahrscheinlich wert, dass Sie etwas detaillierter hinzufügen - z. B. die spezifischen Spalten- und Tabellennamen
Jonathan
1

Ich hatte ein ähnliches Problem beim Speichern einer Django-MySQL-Datenbank mit einer einzelnen Tabelle. Ich konnte das Problem beheben, indem ich die Datenbank in eine Textdatei kopierte, die betreffende Tabelle mit Emacs an das Ende der Datei verschob und die geänderte SQL-Dump-Datei in die neue Instanz importierte.

HTH Uwe

Staubsauger
quelle
1

Ich habe das Problem behoben, indem ich die Variable akzeptiert habe null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
Fahmi
quelle
1

Ich habe das gleiche Problem beim Ausführen einer Reihe von MySQL-Befehlen. Meins tritt beim Erstellen einer Tabelle auf, wenn ein Fremdschlüssel auf eine andere Tabelle verwiesen wird, die noch nicht erstellt wurde. Es ist die Reihenfolge der Tabellenexistenz vor dem Referenzieren.

Die Lösung: Erstellen Sie zuerst die übergeordneten Tabellen, bevor Sie eine untergeordnete Tabelle mit einem Fremdschlüssel erstellen.

ronIT
quelle
1

Erstellen Sie die Tabelle ohne Fremdschlüssel und legen Sie den Fremdschlüssel separat fest.

festgefahrener Helfer
quelle