MySQL: no se puede crear la tabla (errno: 150)

156

Estoy tratando de importar un archivo .sql y no puedo crear tablas.

Aquí está la consulta que falla:

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;    

Exporté el .sql de la misma base de datos, descarté todas las tablas y ahora estoy tratando de importarlo, ¿por qué falla?

MySQL: no se puede crear la tabla './dbname/data.frm' (errno: 150)

gtilx
fuente
1
Para esencialmente todas las causas de este error, aquí hay un recurso exhaustivo para lo que causa errno 150 (y errno 121 / otros errores de clave externa) en MySQL.
John Smith
21
Descubrí que las columnas deben ser idénticas (incluso la bandera sin firmar debe coincidir).
Justin Skiles
3
@JohnSmith ... ¿dónde?
Charles Wood
3
Sugiero leer esta publicación de blog que enumera 10 causas posibles: verysimple.com/2006/10/22/…
Mark Amery
@CharlesWood: " John Smith ... visto el 6 de abril de 13 a las 19:29 ", eso es aproximadamente tres meses antes de su comentario. ¡Tengo miedo de que no se revele un misterio de "dónde" hasta el final de este mundo aburrido! :>
trejder

Respuestas:

167

De MySQL - Documentación de restricciones de CLAVE EXTRANJERA :

Si vuelve a crear una tabla que se descartó, debe tener una definición que se ajuste a las restricciones de clave externa que hacen referencia a ella. Debe tener los nombres y tipos de columna correctos, y debe tener índices en las claves referenciadas, como se indicó anteriormente. Si no se cumplen, MySQL devuelve el Error 1005 y hace referencia al Error 150 en el mensaje de error, lo que significa que no se formó correctamente una restricción de clave externa. De manera similar, si una ALTER TABLE falla debido al Error 150, esto significa que una definición de clave foránea se formaría incorrectamente para la tabla alterada.

Ponis OMG
fuente
1
¿Pueden dos columnas de una tabla hacer referencia a una columna de otra tabla, donde es PK?
Eugene
1
@Eugene: cada una de las dos columnas puede tener una relación de clave externa con el PK en otra tabla, no ambas columnas como una relación de clave externa única.
OMG Ponies
1
@OMGPonies: ¡Gracias por responder a esta pregunta! ... Lo estaba buscando ... También hice una pregunta aquí stackoverflow.com/questions/13487010/… .... Aunque tengo algunas buenas respuestas pero quiero estar conforme Whether its possible to write Nested Query for my problem? .. ¡Te pediría que me contestaras también!
Grijesh Chauhan
19
Mi error fue que la tabla maestra tenía MyISAM y la tabla secundaria del motor InnoDB. El script create.sql actual estaba usando InnoDB para todas las tablas, pero tenía una instalación muy muy antigua donde el primer script usaba MyISAM.
Whome
2
@Whome - Sí, me encontré con el mismo problema aquí.
Aroth
96

El error 150 significa que tiene un problema con su clave externa. ¿Posiblemente la clave en la tabla extranjera no es exactamente el mismo tipo?

Dan McGrath
fuente
15
Gracias :) para mí, los tipos de datos son INT pero uno sin firmar mientras que el otro no lo es
Anh Nguyen
66
A menudo me encuentro con BIGINTvs INTcuando uso generadores de esquemas.
Xeoncross
Me encontré con el mismo problema cuando la clave externa no es el valor INT. La columna debe ser ÚNICA cuando la clave externa se refiere a ella.
PhatHV
62

Puede obtener el mensaje de error real ejecutando SHOW ENGINE INNODB STATUS;y luego buscando LATEST FOREIGN KEY ERRORen la salida.

Fuente: respuesta de otro usuario en una pregunta similar

Denilson Sá Maia
fuente
77
Esto es realmente muy útil. Te dice el error exacto.
Csongor Fagyal
Gracias. Es una pena que MySQL Workbench no haga uso de esto.
scipilot
Increíble. Esto es muy útil Te dice el error exacto. La mía fue, haber hecho que la columna sea NULABLE pero había establecido "on delete set null". Muchas gracias.
Abhishek Saini
Si tiene privilegios en su servidor :(
Christopher Smit
30

Los tipos de datos deben coincidir exactamente. Si se trata de tipos varchar, las tablas deben usar la misma clasificación.

Esben Skov Pedersen
fuente
44
Gracias por el bit de colación.
Arahant
25

Creo que todas estas respuestas, aunque correctas, son engañosas a la pregunta.

La respuesta real es esta antes de comenzar una restauración, si está restaurando un archivo de volcado con claves foráneas:

SET FOREIGN_KEY_CHECKS=0;

porque, naturalmente, la restauración creará algunas restricciones antes de que la tabla foránea exista.

colin
fuente
Hacer esto no funcionó para mí, todavía da el error. ¿Algunas ideas?
Joseph Astrahan el
24

En algunos casos, puede encontrar este mensaje de error si hay diferentes motores entre las tablas relacionadas. Por ejemplo, una tabla puede estar usando InnoDB mientras que la otra usa MyISAM. Ambos necesitan ser iguales

Pi.
fuente
Gracias, este fue mi problema.
scipilot
Ese fue mi problema. Gracias
thed0ctor
Esto puede suceder si creó un archivo sql de una tabla innodb usando mysqldump y se exportaron como myisam talbes.
Amado Martinez
11

Error no 150 significa una falla de restricción de clave externa. Probablemente esté creando esta tabla antes de la tabla de la que depende la clave externa (tabla keywords). Cree esa tabla primero y debería funcionar bien.

Si no es así, elimine la declaración de clave externa y agréguela después de crear la tabla; obtendrá un mensaje de error más significativo sobre el error de restricción específica.

Eran Galperin
fuente
10

Hay bastantes cosas que pueden causar errno 150, por lo que para las personas que buscan este tema, esto es lo que creo que es una lista cercana a exhaustiva ( Causas de origen de Errno 150 ):

Para errno 150 o errno 121, simplemente escribiendo SHOW ENGINE INNODB STATUS, hay una sección llamada "ÚLTIMO ERROR DE CLAVE EXTRANJERA". Debajo de eso, le dará un mensaje de error muy útil, que generalmente le dirá de inmediato cuál es el problema. Necesitas privilegios SUPER para ejecutarlo, así que si no tienes eso, solo tendrás que probar los siguientes escenarios.

1) Los tipos de datos no coinciden: los tipos de las columnas deben ser los mismos

2) Columnas principales no indexadas (o indexadas en orden incorrecto)

3) Las colaciones de columnas no coinciden

4) Usar SET NULL en una columna NOT NULL

5) Las intercalaciones de tablas no coinciden: incluso si las intercalaciones de columnas coinciden, en algunas versiones de MySQL esto puede ser un problema.

6) La columna principal no existe realmente en la tabla principal. Revise la ortografía (y quizás un espacio al principio o al final de la columna)

7) Uno de los índices en una de las columnas está incompleto, o la columna es demasiado larga para un índice completo. Tenga en cuenta que MySQL (a menos que lo ajuste) tiene una longitud máxima de clave de una sola columna de 767 bytes (esto corresponde a una columna UTF varchar (255))

En caso de que obtenga un errno 121, aquí hay un par de causas:

1) El nombre de restricción que eligió ya está tomado

2) En algunos sistemas si hay una diferencia de caso en su declaración y nombres de tabla. Esto puede morderte si vas de un servidor a otro que tiene diferentes reglas de manejo de casos.

juacala
fuente
En algunas versiones obtienes un errno 150 si la tabla no es innodb, pero en algunas versiones simplemente falla en silencio.
juacala
Gracias, esto fue genial: | ------------------------ | ÚLTIMO ERROR DE CLAVE EXTRANJERA | ------------------------ | Ha definido una condición SET NULL aunque algunas de las | Las columnas se definen como NOT NULL.
Sam Critchley
8

A veces MySQL es súper estúpido: puedo entender la causa de las claves foráneas ... pero en mi caso, acabo de descartar toda la base de datos y sigo recibiendo el error ... ¿por qué? Quiero decir, ya no hay una base de datos ... y el usuario sql que estoy usando no tiene acceso a ninguna otra base de datos en el servidor ... quiero decir, el servidor está "vacío" para el usuario actual y todavía obtengo ¿este error? Lo siento, pero supongo que MySQL me está mintiendo ... pero puedo lidiar con eso :) Simplemente agregue estas dos líneas de SQL alrededor de su declaración fucky:

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

Ahora se debe ejecutar el sql ... Si realmente tiene un problema de clave externa, aparecerá en la línea donde habilitará las comprobaciones nuevamente; esto fallará entonces ... pero mi servidor está en silencio :)

jebbie
fuente
Esto puede causar problemas si en realidad hay diferencias entre la columna y la columna a la que hace referencia. Por ejemplo. Supongamos que la columna a la que se hace referencia es un varchar (200) y el referente es varchar (50), luego, cuando se intenta una cascada, puede producirse un comportamiento extraño. No me he encontrado con un problema en el que se emite errno 150 debido a la falta de coincidencia de datos.
juacala
Perspectiva interesante @juacala :) Divertido para mí es único, cada vez que me encuentro con esto, mi enfoque siempre lo solucionó ... hasta hoy al menos: D Pero nunca dejamos de aprender, cierto;)
jebbie
Esto realmente me ayudó con un script generado por liquibase. El script se ejecutó sin problemas en MySQL> 5.5, pero falló para la versión 5.1.
delbertooo
4

Después de navegar por las respuestas anteriores y experimentar un poco, esta es una forma efectiva de resolver errores de clave externa en MySQL (1005 - error 150).

Para que la clave externa se cree correctamente, todo lo que MySQL pide es:

  • Todas las claves referenciadas DEBEN tener un índice PRIMARIO o ÚNICO.
  • La columna de referencia nuevamente DEBE tener un tipo de datos idéntico a la columna de referencia.

Satisfaga estos requisitos y todo estará bien.

Davies Malesi
fuente
4

Experimenté este error cuando porté la aplicación de Windows a Linux. En Windows, los nombres de las tablas de la base de datos no distinguen entre mayúsculas y minúsculas, y en Linux distinguen entre mayúsculas y minúsculas, probablemente debido a la diferencia del sistema de archivos. Entonces, en la tabla de Windows Table1es lo mismo que table1, y en REFERENCESambos table1y Table1funciona. En Linux, cuando la aplicación se usaba en table1lugar de Table1cuando creaba la estructura de la base de datos, vi el error # 150; cuando hice el caso correcto de los caracteres en las Table1referencias, también comenzó a funcionar en Linux. Por lo tanto, si nada más ayuda, asegúrese de REFERENCESusar el caso de caracteres correcto en el nombre de la tabla cuando esté en Linux.

Vitalii
fuente
¡Este también fue mi caso! Mover el script de una versión que no distingue entre mayúsculas y minúsculas (OS X) a una versión de mysql (Debian) que distingue entre mayúsculas y minúsculas.
mircealungu
3

Cambie los motores de sus tablas, solo innoDB admite claves foráneas

Lappies
fuente
3

Si la tabla PK se crea en un CHARSET y luego crea la tabla FK en otro CHARSET ... entonces también podría obtener este error ... También obtuve este error, pero después de cambiar el juego de caracteres a PK charset, se ejecutó sin errores

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
fuente
3

Este error puede ocurrir si dos tablas tienen una referencia, por ejemplo, una tabla es Estudiante y otra tabla es Educación, y queremos que la tabla Educación tenga una referencia de clave externa de la tabla Estudiante. En este caso, el tipo de datos de columna para ambas tablas debe ser el mismo, de lo contrario generará un error.

manzarul haque
fuente
3

En la mayoría de los casos, el problema se debe a la diferencia ENGINE. Si InnoDB crea el padre, entonces MyISAM crea las tablas a las que se hace referencia y viceversa.

Sunil Kumar Mohanty
fuente
3

En mi caso. Tuve problemas con el motor y el juego de caracteres porque mi servidor Hosting cambió la configuración y mis nuevas tablas eran MyISAM, pero mis tablas anteriores son InnoDB. Solo he cambiado.

Ignacio Hernández
fuente
Esto era correcto para mí, porque estaba alterando una base de datos que no había creado.
FonzTech
3

por lo general, la falta de coincidencia entre la clave externa y la clave primaria provoca el error: 150.

La clave externa debe tener el mismo tipo de datos que la clave primaria . Además, si la clave primaria no está firmada , la clave externa también debe estar sin firmar .

Rakesh
fuente
3

Tuve el mismo problema Estaba relacionado con la columna Collation de la tabla y el conjunto de caracteres . Asegúrese de que el conjunto de caracteres y la clasificación deben ser iguales para ambas columnas en dos tablas. Si desea establecer una clave externa en eso. Ejemplo- Si pones clave externa en la columna ID de usuario de la tabla userimage referencia a la columna ID de usuario de los usuarios table.Then colación debe ser el mismo que es utf8_general_ci y juego de caracteres UTF-8 para ambas columnas de tablas. Generalmente, cuando crea una tabla, mysql toma estas dos configuraciones de la configuración del servidor.

Sushilkumar
fuente
¿Por qué no vi este poist antes? Pasé una hora descubriendo la causa raíz. Fue el juego de caracteres en mi caso. Las tablas referenciadas y de referencia deben tener el mismo juego de caracteres.
Sujit Joshi
2

Asegúrese de que tanto su columna de clave principal como la columna a la que se hace referencia tengan los mismos tipos de datos y atributos (sin signo, binario, sin signo, zerofill, etc.).

Basit
fuente
2

Un caso real es cuando ha utilizado una herramienta MySQL (Sequel Pro en mi caso) para cambiar el nombre de una base de datos. Luego creó una base de datos con el mismo nombre.

Esto mantuvo las restricciones de clave externa para el mismo nombre de base de datos, por lo que la base de datos renombrada (por ejemplo, my_db_renamed) tenía restricciones de clave externa en la base de datos recién creada (my_db)

No estoy seguro de si esto es un error en Sequel Pro, o si algún caso de uso requiere este comportamiento, pero me costó la mayor parte de una mañana: /

chim
fuente
2

Yo tenía el mismo error. En mi caso, la razón del error fue que tenía una instrucción ON DELETE SET NULL en la restricción, mientras que el campo en el que puse la restricción en su definición tenía una instrucción NOT NULL. Permitir NULL en el campo resolvió el problema.

Wilbert van Diemen
fuente
2

Enfrenté este tipo de problema al crear DB desde el archivo de texto.

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 

Acabo de escribir las líneas anteriores en Create.bat y ejecuto el archivo bat.

Mi error está en el orden de ejecución de la secuencia en mis archivos sql. Traté de crear una tabla con clave primaria y también clave externa. Mientras se ejecuta, buscará la tabla de referencia, pero las tablas no están allí. Entonces devolverá ese tipo de error.

Si crea tablas con clave externa, compruebe que las tablas de referencia estaban presentes o no. Y también verifique el nombre de las tablas y campos de referencia.

Dharani Dharan
fuente
En otras palabras, trató de crear una tabla con una clave externa que apunta a otra tabla que aún no existía. Cree las tablas en el orden correcto para resolver el problema.
Vincent
2

Tuve un problema similar, pero el mío fue porque estaba agregando un nuevo campo a una tabla existente que tenía datos, y el nuevo campo hacía referencia a otro campo de la tabla principal y también tenía la Definición de NOT NULL y sin ningún VALOR POR DEFECTO. - Descubrí que la razón por la que las cosas no funcionaban era porque

  1. Mi nuevo campo necesitaba completar automáticamente los campos en blanco con un valor de la tabla principal en cada registro, antes de que la restricción pudiera aplicarse. Cada vez que se aplica la restricción, debe dejar intacta la integridad de los datos de la tabla. La implementación de la restricción (clave externa), sin embargo, había algunos registros de la base de datos que no tenían los valores de la tabla principal significaría que los datos están corruptos, por lo que MySQL NUNCA APLICARÍA SU RESTRICCIÓN

Es importante recordar que, en circunstancias normales, si planificó su base de datos con suficiente anticipación e implementó restricciones antes de la inserción de datos, se evitaría este escenario en particular

El enfoque más fácil para evitar este problema es

  • Guarde los datos de las tablas de su base de datos.
  • Truncar los datos de la tabla (y los artefactos de la tabla, es decir, índices, etc.)
  • Aplicar las restricciones
  • Importa tus datos

Espero que esto ayude a alguien

Chitwarnold
fuente
1

Quizás esto ayude? La definición de la columna de clave principal debe ser exactamente la misma que la columna de clave externa.

Mukus
fuente
1

Asegúrese de que todas las tablas pueden admitir claves foráneas - motor InnoDB

joksy82
fuente
1

La columna de la tabla PADRE a la que se refiere desde la tabla secundaria tiene que ser única. Si no es así, causa un error no 150.

Dila Ram Gurung
fuente
probablemente valdría la pena agregar un poco más de detalles, por ejemplo, los nombres específicos de la columna y la tabla
Jonathan el
1

Tuve un problema similar al volcar una base de datos mysql de Django con una sola tabla. Pude solucionar el problema volcando la base de datos a un archivo de texto, moviendo la tabla en cuestión al final del archivo usando emacs e importando el archivo de volcado sql modificado a la nueva instancia.

HTH Uwe

aspiradora
fuente
1

He corregido el problema haciendo que la variable acepte null

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

Tuve el mismo problema al ejecutar una serie de comandos MySQL. La mía ocurre durante la creación de una tabla cuando se hace referencia a una clave externa a otra tabla que aún no se creó. Es la secuencia de la existencia de la tabla antes de hacer referencia.

La solución: cree las tablas primarias antes de crear una tabla secundaria que tenga una clave externa.

ronIT
fuente
1

Cree la tabla sin clave externa, luego configure la clave externa por separado.

atascado
fuente