MySQL: impossibile creare la tabella (errno: 150)


156

Sto cercando di importare un file .sql e la sua mancata creazione di tabelle.

Ecco la query che fallisce:

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;    

Ho esportato il .sql dallo stesso database, ho lasciato cadere tutte le tabelle e ora sto cercando di importarlo, perché non riesce?

MySQL: impossibile creare la tabella './dbname/data.frm' (errno: 150)


1
Per sostanzialmente tutte le cause di questo errore, ecco una risorsa esaustiva per ciò che causa errno 150 (e errno 121 / altri errori di chiave esterna) in MySQL.
John Smith,

21
Ho scoperto che le colonne devono essere identiche (anche la bandiera senza segno deve corrispondere).
Justin Skiles,

3
@JohnSmith ... dove?
Charles Wood,

3
Suggerisco di leggere questo post sul blog che elenca 10 possibili cause: verysimple.com/2006/10/22/…
Mark Amery

@CharlesWood: " John Smith ... visto il 6 aprile 13 alle 19:29 ", circa tre mesi prima del tuo commento. Ho paura che un mistero di "dove" non sarà rivelato fino alla fine di questo mondo cupo! :>
trejder

Risposte:


167

Dalla documentazione sui vincoli di MySQL - FOREIGN KEY :

Se si ricrea una tabella che è stata eliminata, deve avere una definizione conforme ai vincoli di chiave esterna che la fanno riferimento. Deve avere nomi e tipi di colonne corretti e deve avere indici sulle chiavi di riferimento, come indicato in precedenza. Se questi non sono soddisfatti, MySQL restituisce l'errore 1005 e fa riferimento all'errore 150 nel messaggio di errore, il che significa che un vincolo di chiave esterna non è stato formato correttamente. Allo stesso modo, se una tabella ALTER non riesce a causa dell'errore 150, ciò significa che una definizione di chiave esterna verrebbe formata in modo errato per la tabella modificata.


1
Due colonne di una tabella possono fare riferimento a una colonna di un'altra tabella, dove si trova PK?
Eugene,

1
@Eugene: ciascuna delle due colonne può avere una relazione di chiave esterna con il PK in un'altra tabella, non entrambe le colonne come singola relazione di chiave esterna.
OMG Pony

1
@OMGPonies: Grazie per aver risposto a questa domanda! .. La stavo cercando ... Ho anche fatto una domanda qui stackoverflow.com/questions/13487010/… .... Anche se ho delle buone risposte ma voglio essere conforme Whether its possible to write Nested Query for my problem? .. ti chiederei di rispondere anche a me!
Grijesh Chauhan,

19
Il mio errore era la tabella principale con MyISAM e il motore InnoDB della tabella figlio. Lo script create.sql corrente utilizzava InnoDB per tutte le tabelle, ma avevo un'installazione molto vecchia in cui il primo script utilizzava MyISAM.
Chi l'

2
@Whome - Sì, ho riscontrato lo stesso problema qui.
aroth,

96

L'errore 150 indica che hai un problema con la tua chiave esterna. Forse la chiave sul tavolo esterno non è esattamente lo stesso tipo?


15
Grazie :) per me, i tipi di dati sono INT ma uno non firmato mentre l'altro no
Anh Nguyen

6
Mi capita spesso di imbattermi in BIGINTvs INTquando utilizzo generatori di schemi.
Xeoncross,

Ho riscontrato lo stesso problema quando la chiave esterna non è un valore INT. La colonna deve essere UNICA quando la chiave esterna si riferisce ad essa.
PhatHV,

62

È possibile ottenere il messaggio di errore effettivo eseguendo SHOW ENGINE INNODB STATUS;e quindi cercando LATEST FOREIGN KEY ERRORnell'output.

Fonte: risposta di un altro utente in una domanda simile


7
Questo in realtà è molto utile. Ti dice l'errore esatto.
Csongor Fagyal,

Grazie. È un peccato che MySQL Workbench non ne faccia uso.
scipilot,

Eccezionale. Questo è molto utile Ti dice l'errore esatto. Il mio era, aver reso la colonna NULLABILE ma aver impostato "on delete set null". Grazie mille.
Abhishek Saini,

Se hai privilegi sul tuo server :(
Christopher Smit,

30

I tipi di dati devono corrispondere esattamente. Se hai a che fare con tipi varchar, le tabelle devono usare le stesse regole di confronto.


4
Grazie per il bit di confronto.
Arahant,

25

Penso che tutte queste risposte siano corrette e fuorvianti alla domanda.

La risposta effettiva è questa prima di iniziare un ripristino, se stai ripristinando un file di dump con chiavi esterne:

SET FOREIGN_KEY_CHECKS=0;

perché naturalmente il ripristino creerà alcuni vincoli prima ancora che esista la tabella esterna.


In questo modo non ha funzionato per me, dà ancora l'errore. Qualche idea?
Joseph Astrahan,

24

In alcuni casi, è possibile che venga visualizzato questo messaggio di errore se sono presenti motori diversi tra le relative tabelle. Ad esempio, una tabella potrebbe utilizzare InnoDB mentre l'altra utilizza MyISAM. Entrambi devono essere uguali


Grazie - questo era il mio problema.
scipilot,

Questo era il mio problema. Grazie
thed0ctor

Questo può accadere se hai creato un file sql della tabella innodb usando mysqldump e invece sono stati esportati come talis myisam.
Amado Martinez,

11

Errore n. 150 indica un errore del vincolo di chiave esterna. Probabilmente stai creando questa tabella prima della tabella da cui dipende la chiave esterna (tabella keywords). Crea prima quella tabella e dovrebbe funzionare bene.

In caso contrario, rimuovere l'istruzione di chiave esterna e aggiungerla dopo la creazione della tabella: verrà visualizzato un messaggio di errore più significativo sull'errore del vincolo specifico.


10

Ci sono alcune cose che possono causare errno 150, quindi per le persone che cercano questo argomento, ecco quello che penso sia un elenco vicino all'esaustivo (fonte Cause di Errno 150 ):

Per errno 150 o errno 121, semplicemente digitando SHOW ENGINE INNODB STATUS, c'è una sezione chiamata "LATEST KEY ERROR ESTERO". Sotto questo ti darà un messaggio di errore molto utile, che in genere ti dirà subito qual è il problema. Hai bisogno dei privilegi SUPER per eseguirlo, quindi se non lo possiedi, dovrai solo provare i seguenti scenari.

1) I tipi di dati non corrispondono: i tipi di colonne devono essere uguali

2) Colonne principali non indicizzate (o indicizzate in ordine errato)

3) Le regole di confronto delle colonne non corrispondono

4) Utilizzo di SET NULL su una colonna NOT NULL

5) Le regole di confronto delle tabelle non corrispondono: anche se le regole di confronto delle colonne corrispondono, in alcune versioni di MySQL questo può essere un problema.

6) La colonna padre non esiste realmente nella tabella padre. Controlla l'ortografia (e forse uno spazio all'inizio o alla fine della colonna)

7) Uno degli indici su una delle colonne è incompleto o la colonna è troppo lunga per un indice completo. Nota che MySQL (a meno che non lo modifichi) ha una lunghezza massima della chiave a colonna singola di 767 byte (corrisponde a una colonna UTF varchar (255))

Nel caso in cui ricevi un errore 121, ecco un paio di cause:

1) Il nome del vincolo scelto è già stato preso

2) Su alcuni sistemi se c'è una differenza tra maiuscole e minuscole nell'istruzione e nei nomi delle tabelle. Questo può morderti se passi da un server a un altro con regole di gestione dei casi diverse.


In alcune versioni si ottiene un errore 150 se la tabella non è innodb, ma in alcune versioni fallisce silenziosamente.
juacala,

Grazie, è stato fantastico: | ------------------------ | ULTIMO ERRORE CHIAVE ESTERO | ------------------------ | È stata definita una condizione SET NULL anche se alcuni dei | le colonne sono definite come NON NULL.
Sam Critchley,

8

A volte MySQL è semplicemente super stupido - posso capire la causa delle chiavi esterne ... ma nel mio caso, ho appena lasciato cadere l'intero database e continuo a ricevere l'errore ... perché? voglio dire, non c'è più un database ... e l'utente sql che sto usando non ha accesso a nessun altro db sul server ... voglio dire, il server è "vuoto" per l'utente corrente e ancora ottengo questo errore? Scusate ma immagino che MySQL mi stia mentendo ... ma posso affrontarlo :) Aggiungete solo queste due righe di SQL attorno alla vostra dichiarazione fottuta:

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

Ora il sql dovrebbe essere eseguito ... Se hai davvero un problema con una chiave esterna, ti verrà mostrato dalla riga in cui abiliterai di nuovo i controlli - questo fallirà allora .. ma il mio server è silenzioso :)


Ciò potrebbe causare problemi se ci sono effettivamente differenze tra la colonna e la colonna a cui fa riferimento. Per esempio. Supponiamo che la colonna referenziata sia varchar (200) e che il referrer sia varchar (50), quindi quando si tenta una cascata si potrebbe verificare un comportamento strano. Non ho riscontrato un problema in cui viene emesso errno 150 a causa della mancata corrispondenza dei dati.
juacala,

Intuizione interessante @juacala :) Per me è divertente solo ogni volta che mi imbatto in questo, il mio approccio lo fissa sempre ... almeno fino ad oggi: D Ma non smettiamo mai di imparare, giusto;)
jebbie

Questo in realtà mi ha aiutato con una sceneggiatura liquibase generata. Lo script ha funzionato perfettamente su MySQL> 5.5, ma non è riuscito per la versione 5.1.
delbertooo,

4

Dopo aver esaminato le risposte sopra e aver sperimentato un po ', questo è un modo efficace per risolvere gli errori di chiave esterna in MySQL (1005 - errore 150).

Per creare correttamente la chiave esterna, tutto ciò che MySQL richiede è:

  • Tutte le chiavi referenziate DEVONO avere un indice PRIMARIO o UNICO.
  • La colonna di riferimento DEVE di nuovo avere un tipo di dati identico alla colonna di riferimento.

Soddisfa questi requisiti e tutto andrà bene.


4

Ho riscontrato questo errore quando ho portato l'applicazione Windows su Linux. In Windows, i nomi delle tabelle del database non fanno distinzione tra maiuscole e minuscole e in Linux sono sensibili al maiuscolo / minuscolo, probabilmente a causa della differenza del file system. Quindi, sulla tabella di Windows Table1è lo stesso di table1, e in REFERENCESentrambi table1e Table1funziona. Su Linux, quando è stata utilizzata l'applicazione table1anziché Table1quando ha creato la struttura del database ho visto l'errore n. 150; quando ho fatto il caso corretto del personaggio nei Table1riferimenti, ha iniziato a funzionare anche su Linux. Quindi, se nient'altro aiuta, assicurati REFERENCESdi usare il caso di caratteri corretto nel nome della tabella quando sei su Linux.


Questo è stato anche il mio caso! Spostare lo script da una distinzione tra maiuscole e minuscole (OS X) in una versione mysql con distinzione tra maiuscole e minuscole (Debian).
mircealungu,

3

Cambia i motori delle tue tabelle, solo innoDB supporta le chiavi esterne


3

Se la tabella PK viene creata in un CHARSET e quindi si crea la tabella FK in un altro CHARSET ... quindi si potrebbe ottenere questo errore ... Anche io ho questo errore ma dopo aver cambiato il set di caratteri in set di caratteri PK, è stato eseguito senza errori

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;

3

Questo errore può verificarsi se due tabelle hanno un riferimento, ad esempio una tabella è Student e un'altra tabella Education e vogliamo che la tabella Education abbia un riferimento di chiave esterna della tabella Student. In questo caso il tipo di dati della colonna per entrambe le tabelle dovrebbe essere lo stesso, altrimenti genererà un errore.


3

Nella maggior parte dei casi il problema è dovuto alla differenza ENGINE. Se il genitore è creato da InnoDB, le tabelle di riferimento dovrebbero essere create da MyISAM e viceversa


3

Nel mio caso. Ho avuto problemi con il motore e il set di caratteri perché il mio server di hosting modifica le impostazioni e le mie nuove tabelle erano MyISAM ma le mie vecchie tabelle sono InnoDB. Sono appena cambiato.


Questo era giusto per me, perché stavo modificando un database non creato da me.
FonzTech,

3

di solito, la mancata corrispondenza tra chiave esterna e chiave primaria provoca l'errore: 150.

La chiave esterna deve avere lo stesso tipo di dati della chiave primaria . Inoltre, se la chiave primaria non è firmata, anche la chiave esterna deve essere senza segno .


3

Ho avuto lo stesso problema. Era correlato alla colonna della tabella Fascicolazione e set di caratteri . Assicurarsi che il set di caratteri e le regole di confronto debbano essere uguali per entrambe le colonne su due tabelle. Se si desidera impostare una chiave esterna su quello. Esempio: se si inserisce una chiave esterna nella colonna userID della tabella userImage che fa riferimento alla colonna userID della tabella degli utenti, quindi le regole di confronto devono essere uguali a utf8_general_ci e al set di caratteri utf8 per entrambe le colonne delle tabelle. Generalmente quando si crea una tabella mysql prende queste due configurazioni dalle impostazioni del server.


Perché non ho visto questo poista prima !? Ho trascorso un'ora a capire la causa principale. Era il set di caratteri nel mio caso. Le tabelle di riferimento e di riferimento devono avere lo stesso set di caratteri.
Sujit Joshi,

2

Assicurati che sia la colonna della chiave primaria sia la colonna di riferimento abbiano gli stessi tipi e attributi di dati (zerofill senza segno, binario, senza segno, ecc.).


2

Un vero caso limite è quello in cui hai usato uno strumento MySQL, (Sequel Pro nel mio caso) per rinominare un database. Quindi ha creato un database con lo stesso nome.

Ciò ha mantenuto i vincoli di chiave esterna con lo stesso nome di database, quindi il database rinominato (ad esempio my_db_renamed) aveva vincoli di chiave esterna nel database appena creato (my_db)

Non sono sicuro se questo è un bug in Sequel Pro o se alcuni casi d'uso richiedono questo comportamento, ma mi è costato la parte migliore di una mattinata: /


2

Ho avuto lo stesso errore. Nel mio caso il motivo dell'errore era che avevo un'istruzione ON DELETE SET NULL nel vincolo mentre il campo su cui ho inserito il vincolo nella sua definizione aveva un'istruzione NOT NULL. Consentire NULL nel campo ha risolto il problema.


2

Ho riscontrato questo tipo di problema durante la creazione di DB dal file di testo.

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 

Ho appena scritto le righe sopra Create.bated eseguo il file bat.

Il mio errore è nell'ordine di esecuzione dei miei file sql. Ho provato a creare una tabella con chiave primaria e anche chiave esterna. Durante l'esecuzione cercherà la tabella di riferimento ma le tabelle non sono presenti. Quindi restituirà questo tipo di errore.

Se si creano tabelle con chiave esterna, verificare che le tabelle di riferimento fossero presenti o meno. E controlla anche il nome delle tabelle e dei campi di riferimento.


In altre parole, hai provato a creare una tabella con una chiave esterna che punta a un'altra tabella che non esisteva ancora. Creare le tabelle nell'ordine corretto per risolvere il problema.
Vincent,

2

Avevo un problema simile, ma il mio era perché stavo aggiungendo un nuovo campo a una tabella esistente che aveva dati, e il nuovo campo faceva riferimento a un altro campo dalla tabella padre e aveva anche la definizione di NOT NULL e senza VALORI DI DEFAULT. - Ho scoperto che il motivo per cui le cose non funzionavano era perché

  1. Il mio nuovo campo doveva riempire automaticamente i campi vuoti con un valore dalla tabella padre su ciascun record, prima che il vincolo potesse essere applicato. Ogni volta che viene applicato il vincolo, è necessario lasciare integra l'integrità dei dati della tabella. L'implementazione del vincolo (chiave esterna) eppure c'erano alcuni record di database che non avevano i valori dalla tabella padre significherebbe che i dati sono corrotti, quindi MySQL non rafforzerà MAI IL VOSTRO VINCITORE

È importante ricordare che in circostanze normali se si pianificasse il database con largo anticipo e si implementassero vincoli prima dell'inserimento dei dati, questo particolare scenario sarebbe evitato

L'approccio più semplice per evitare questo gotcha è quello di

  • Salvare i dati delle tabelle del database
  • Tronca i dati della tabella (e artefatti della tabella, ad esempio indici, ecc.)
  • Applica i vincoli
  • Importa i tuoi dati

Spero che questo aiuti qualcuno


1

Forse questo aiuterà? La definizione della colonna chiave primaria dovrebbe essere esattamente la stessa della colonna chiave esterna.


1

Assicurarsi che tutte le tabelle possano supportare la chiave esterna - motore InnoDB


1

La colonna della tabella PARENT a cui ti stai riferendo dalla tabella figlio deve essere unica. In caso contrario, causare un errore n. 150.


probabilmente varrebbe la pena aggiungere un po 'più in dettaglio - ad es. i nomi specifici di colonne e tabelle
Jonathan

1

Ho avuto un problema simile durante il dumping di un database mysql Django con una sola tabella. Sono stato in grado di risolvere il problema scaricando il database in un file di testo, spostando la tabella in questione alla fine del file usando emacs e importando il file dump sql modificato nella nuova istanza.

HTH Uwe


1

Ho corretto il problema facendo accettare la variabile null

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

1

Ho avuto lo stesso problema durante l'esecuzione di una serie di comandi MySQL. Il mio si verifica durante la creazione di una tabella quando si fa riferimento a una chiave esterna ad un'altra tabella che non è stata ancora creata. È la sequenza dell'esistenza della tabella prima del riferimento.

La soluzione: creare le tabelle padre prima di creare una tabella figlio con una chiave esterna.


1

Creare la tabella senza chiave esterna, quindi impostare la chiave esterna separatamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.