web-dev-qa-db-ger.com

MySQL-Fremdschlüsselfehler 1005, Fehler 150

Ich mache eine kleine Datenbank mit MySQL Workbench. Ich habe eine Haupttabelle namens "Immobili", die einen Primärschlüssel aus vier Spalten enthält: (Comune, Via, Civico, Immobile).

Nun habe ich noch drei weitere Tabellen, die denselben Primärschlüssel haben (Comune, Via, Civico, Immobile), aber diese Felder beziehen sich auch auf die Tabelle Immobili.

Erste Frage: Kann ich einen Primärschlüssel erstellen, der auch ein Fremdschlüssel ist?

Zweite Frage: Wenn ich versuche, die Änderungen zu exportieren, heißt es: SQL-Skript auf dem Server ausführen

# ERROR: Error 1005: Can't create table 'dbimmobili.condoni' (errno: 150)

CREATE  TABLE IF NOT EXISTS `dbimmobili`.`Condoni` (

  `ComuneImmobile` VARCHAR(50) NOT NULL ,
  `ViaImmobile` VARCHAR(50) NOT NULL ,
  `CivicoImmobile` VARCHAR(5) NOT NULL ,
  `InternoImmobile` VARCHAR(3) NOT NULL ,
  `ProtocolloNumero` VARCHAR(15) NULL ,
  `DataRichiestaSanatoria` DATE NULL ,
  `DataSanatoria` DATE NULL ,
  `SullePartiEsclusive` TINYINT(1) NULL ,
  `SullePartiComuni` TINYINT(1) NULL ,
  `OblazioneInEuro` DOUBLE NULL ,
  `TecnicoOblazione` VARCHAR(45) NULL ,
  `TelefonoTecnico` VARCHAR(15) NULL ,
  INDEX `ComuneImmobile` (`ComuneImmobile` ASC) ,
  INDEX `ViaImmobile` (`ViaImmobile` ASC) ,
  INDEX `CivicoImmobile` (`CivicoImmobile` ASC) ,
  INDEX `InternoImmobile` (`InternoImmobile` ASC) ,

  PRIMARY KEY (`ComuneImmobile`, `ViaImmobile`, `CivicoImmobile`, `InternoImmobile`) ,

  CONSTRAINT `ComuneImmobile`
    FOREIGN KEY (`ComuneImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ComuneImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `ViaImmobile`
    FOREIGN KEY (`ViaImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ViaImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `CivicoImmobile`
    FOREIGN KEY (`CivicoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`CivicoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `InternoImmobile`
    FOREIGN KEY (`InternoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`InternoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE = InnoDB

Anzeigen des Engine-Status:

Fehler in der Fremdschlüsseleinschränkung der Tabelle dbimmobili/valutazionimercato:

In der referenzierten Tabelle kann kein Index gefunden werden, in dem die referenzierten Spalten als erste Spalte angezeigt werden, oder Spaltenart in der Tabelle und die referenzierte Tabelle stimmen nicht mit der Einschränkung überein. Beachten Sie, dass sich der interne Speichertyp von ENUM und SET in Tabellen geändert hat, die mit> = .__ erstellt wurden. InnoDB-4.1.12 und solche Spalten in alten Tabellen können nicht durch solche Spalten referenziert werden in neuen Tabellen.

Wo mache ich falsch?

36
IssamTP

Beim Erstellen einer Fremdschlüsseleinschränkung erfordert MySQL einen verwendbaren Index sowohl für die referenzierende Tabelle als auch für die referenzierte Tabelle. Der Index für die referenzierende Tabelle wird automatisch erstellt, wenn kein Index vorhanden ist. Der Index für die referenzierte Tabelle muss jedoch manuell erstellt werden ( Source ). Deine scheint zu fehlen.

Testfall:

CREATE TABLE tbl_a (
    id int PRIMARY KEY,
    some_other_id int,
    value int
) ENGINE=INNODB;
Query OK, 0 rows affected (0.10 sec)

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
ERROR 1005 (HY000): Can't create table 'e.tbl_b' (errno: 150)

Wenn wir jedoch einen Index zu some_other_id hinzufügen:

CREATE INDEX ix_some_id ON tbl_a (some_other_id);
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)

In den meisten Situationen ist dies häufig kein Problem, da das Feld, auf das verwiesen wird, häufig der Primärschlüssel der referenzierten Tabelle ist und der Primärschlüssel automatisch indiziert wird.

49
Daniel Vassallo

Vergewissern Sie sich noch einmal, dass die Fremdschlüssel genau den gleichen Typ haben wie das Feld, das Sie in dieser Tabelle haben. Zum Beispiel sollten beide Integer (10) oder Varchar (8) sein, auch die Anzahl der Zeichen. 

29
dmp

Mir ist klar, dass dies ein alter Beitrag ist, aber er hat einen hohen Rang in Google. Ich füge hinzu, was ich für mein Problem gefunden habe. Wenn Sie eine Mischung von Tabellentypen haben (z. B. MyISAM und InnoDB), wird dieser Fehler ebenfalls angezeigt. In diesem Fall ist InnoDB der Standardtabellentyp. Für eine Tabelle war jedoch eine Volltextsuche erforderlich, sodass sie zu MyISAM migriert wurde. In dieser Situation können Sie in der InnoDB-Tabelle keinen Fremdschlüssel erstellen, der auf die MyISAM-Tabelle verweist.

15
Steve

Wenn es sich bei Ihrem Schlüssel um einen CHAR/VARCHAR oder etwas Ähnliches handelt, ist ein anderes mögliches Problem eine andere Sortierung. Prüfen Sie, ob der Zeichensatz gleich ist.

9
Alon Diamant

Ich hatte diesen Fehler und fand den Grund für den Fehler in meinem Fall ... Ich antworte immer noch auf diesen alten Beitrag, da er bei Google ziemlich hoch liegt.

Die Variablen der beiden Spalten, die ich verknüpfen wollte, waren ganze Zahlen, aber bei einem der Ints wurde das Zeichen "unsigned" aktiviert. Einfach das Abwählen des Fehlers behoben.

6
Wafje

Ich habe den gleichen Fehler bekommen. Ich fand die Lösung heraus, dass ich den Primärschlüssel in der Haupttabelle als BIGINT UNSIGNED erstellt hatte, und erklärte ihn in der zweiten Tabelle als Fremdschlüssel als nur BIGINT.

Als ich meinen Fremdschlüssel in der zweiten Tabelle als BIGINT UNSIGED deklarierte, funktionierte alles einwandfrei, und es waren sogar keine Indizes erforderlich, um erstellt zu werden.

Es war also ein Datentyp-Konflikt zwischen dem Primärschlüssel und dem Fremdschlüssel :)

5
iltaf khalid

Ich hatte genau das gleiche Problem, aber die Lösung meines Problems war völlig anders. Ich hatte irgendwo in der Datenbank einen Fremdschlüssel mit demselben Namen. Das hat den Fehler 1005 verursacht. 

Das Umbenennen des Fremdschlüssels in etwas Spezielleres für diese Situation hat das Problem gelöst.

4
Sherlock
  1. Stellen Sie sicher, dass beide Tabellen denselben Engine-Typ verwenden.
  2. Stellen Sie sicher, dass die Felder, die Sie indizieren, denselben Typ und dieselbe Länge haben.
3
Jason Rundell

In meinem Fall lag der Fehler an der referencing-Tabelle: MyISAM, wobei referring-Tabelle InnoDB war.

Converted table engine von MyISAM to InnoDB löst das Problem für mich.

ALTER TABLE table_name ENGINE=InnoDB;
3
Rizwan Mumtaz

Ich habe noch nicht den Ruf, Steves Vorschlag zu stimmen, aber er hat mein Problem gelöst. 

In meinem Fall habe ich diesen Fehler erhalten, weil die zwei Tabellen mit unterschiedlichen Datenbank-Engines erstellt wurden - eine war Innodb und die andere MyISAM. 

Sie können den Datenbanktyp folgendermaßen ändern: ALTER TABLE t ENGINE = MYISAM;

@see http://dev.mysql.com/doc/refman/5.1/de/storage-engine-setting.html

1
Fermentation

MySQL ist bekanntermaßen verrückt, insbesondere was Fremdschlüssel und Auslöser betrifft. Ich bin gerade dabei, eine solche Datenbank zu bearbeiten, und bin auf dieses Problem gestoßen. Es ist nicht selbstverständlich oder intuitiv, also geht es hier:

Sie müssen nicht nur prüfen, ob die beiden Spalten, auf die Sie in der Beziehung verweisen möchten, denselben Datentyp haben, sondern auch, ob die Spalte in der Tabelle, auf die Sie verweisen, ein Index ist. Wenn Sie die MySQL Workbench verwenden, wählen Sie die Registerkarte "Indizes" direkt neben "Spalten" und stellen Sie sicher, dass es sich bei der vom Fremdschlüssel referenzierten Spalte um einen Index handelt. Wenn nicht, erstellen Sie einen, benennen Sie ihn mit etwas Sinnvollem und geben Sie ihm den Typ "INDEX".

Es empfiehlt sich, die in Beziehungen enthaltenen Tabellen zu bereinigen, um sicherzustellen, dass bei vorherigen Versuchen keine Indizes erstellt wurden, die Sie nicht möchten oder benötigen.

Ich hoffe, es hat geholfen, einige MySQL-Fehler sind verrückt zu verfolgen.

0

Für mich versuchte ich, ein normales indiziertes Feld in einer untergeordneten Tabelle mit einem Primärschlüssel in der übergeordneten Tabelle abzugleichen. Standardmäßig setzen einige MySQL-Frontend-GUIs wie Sequel Pro den Primärschlüssel als unsigniert dass das untergeordnete Tabellenfeld ebenfalls nicht signiert ist (sofern diese Felder möglicherweise negative Ints enthalten, stellen Sie sicher, dass beide Felder signiert sind).

0
smo0f

Es ist nicht Ihr spezieller Fall, aber es ist für alle anderen interessant, dass dieser Fehler auftreten kann, wenn Sie versuchen, auf einige Felder in einer Tabelle zu verweisen, die nicht den gesamten Primärschlüssel dieser Tabelle darstellen. Das ist natürlich nicht erlaubt.

0
bluish

Erste Frage: Kann ich einen Primärschlüssel erstellen, der auch ein Fremdschlüssel ist?

Ja. Für die MySQL-Workbench habe ich mich nämlich angewöhnt, nur Primärschlüssel für Fremdschlüssel zu verwenden. Reduziert wirklich die zufälligen Fehler, wie er in der Frage angegeben wurde.

# ERROR: Fehler 1005: Die Tabelle 'dbimmobili.condoni' kann nicht erstellt werden (Fehlernummer: 150)

Dies hat etwas mit Indizes zu tun, oder genauer gesagt, wie MySQL Workbench sie interpretiert und damit arbeitet. Es wird wirklich verwirrt, wenn Sie eine Menge im Modell ändern (z. B. Fremdschlüssel, Indizes, Col-Aufträge), und zwar alle in derselben Forward-Engineering-Operation, insbesondere wenn am anderen Ende bereits eine Datenbank vorhanden ist . Ich glaube beispielsweise nicht, dass automatisch erstellte Indizes nach dem Löschen eines Fremdschlüssels automatisch gelöscht werden. 

So habe ich den Fehler behoben, den Sie erhalten haben. Beachten Sie, es scheint umständlich zu sein, aber verglichen mit der Zeit, die ich mit anderen Methoden verbracht habe, ist es nicht so. 

1. Machen Sie alle Fremdschlüssel zu Primärschlüsseln in der Nachschlagetabelle (die 1 von 1 bis viele).  

In meinem Fall bestand die Änderung der ID als PK in Benutzername in Tbl_users, in Benutzername UND Firma in Tbl_companies und in Benutzername UND Firma AND in Tbl_company_contacts. Es ist eine App für mehrere Benutzer, um mehrere Unternehmenskontakte einzugeben, wodurch sich die Kontakte anderer Benutzer überlappen und ausblenden können.

2. Löschen Sie alle Diagrammbeziehungen und alle Tabellenindizes, die keine Primärschlüssel sind.

Dies behebt die meisten Indexprobleme, die tatsächlich durch eine fehlerhafte MySQL-Workbench verursacht werden.

3. Wenn Sie dies von Anfang bis Ende tun, löschen Sie das Schema auf dem Server, damit die mysql workbench nicht über die vorhandenen Indizes verwirrt wird und dort nicht im Modell angezeigt wird (das Problem wird durch den Index und die Fremdschlüsselbeziehung verursacht, nicht Index allein).

Dies reduziert viele Entscheidungen, die die DB, der Server und die MySQL-Workbench treffen müssen. Diese Entscheidungen, wie man etwas weiterentwickeln kann, sind kompliziert und intelligent, aber unvollkommen.

4. Nun, ich betrachte das wieder auf das Quadrat (in der Regel nach einem zu schnellen Entwurf ohne einen schrittweisen Prozess). Ich habe immer noch alle Tische, aber sie sind zu diesem Zeitpunkt sauber. Jetzt nur noch:

Erstens, Forward Engineer, nur um sicherzustellen, dass die Tabellen (ohne Beziehungen) wie erwartet funktionieren.

Folgen Sie der Beziehungskette durch die Primärschlüssel und beginnen Sie mit der obersten Tabelle (ich bin mein Fall tbl_users to tbl_companies). Nach jeder Beziehung sollten Sie den Bearbeiter immer weiterleiten, um sicherzustellen, dass er ausgeführt ist. Speichern Sie dann das Modell und schließen Sie es. Kehren Sie dann das Modell zurück, um sicherzustellen, dass es (nimmt Auf diese Weise können Sie die auftretenden Probleme schnell isolieren. In meinem Fall verbleibt ein Index, der von alten gelöschten Fremdschlüsseln verwendet wird (zwei bis drei Mal).

Und Tadda, wieder da, wo Sie sein mussten.

0
gunslingor

Wenn es zwei Spalten für Primärschlüssel gibt, bilden sie einen zusammengesetzten Primärschlüssel. Daher müssen Sie sicherstellen, dass in der Tabelle, auf die verwiesen wird, auch 2 Spalten desselben Datentyps vorhanden sind.

0
anesumushate

Achten Sie beim Erstellen einer Tabelle auf die ParameterCHARSETundCOLLATE. In Bezug auf FOREIGN KEY Probleme so etwas:

CREATE TABLE yourTableName (
....
....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

In meinem Fall konnte ich die Tabelle nicht mit FOREIGN KEY-Referenzen erstellen. Zuerst bekam ich den Fehlercode 1005, der eigentlich nichts sagt. Dann habe ich COLLATE hinzugefügt und schließlich die Fehlermeldung, die sich über CHARSET beschwert.

Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'

Nach dieser Korrektur wurde mein Problem gelöst.

0
sba

Wenn jemand diesen Fehler mit scheinbar wohlgeformten FK/PK-Beziehungen hat und Sie das visuelle Werkzeug verwendet haben, löschen Sie die betreffenden fk-Spalten und fügen Sie sie erneut zum Werkzeug hinzu. Ich erhielt diesen Fehler immer wieder, bis ich die Verbindungen neu formulierte, wodurch die Probleme gelöst wurden. 

0
munch1324