mysql - secundaria - no puede adicionar clave extranjera constraint
Error de MySQL 1215: No se puede agregar una restricción de clave externa (28)
Estoy intentando enviar el nuevo esquema de ingeniería a mi servidor de base de datos, pero no puedo entender por qué recibo este error. He intentado buscar la respuesta aquí, pero todo lo que he encontrado ha dicho que, ya sea para configurar el motor db en Innodb o para asegurarme de que las claves que trato de usar como clave externa son claves primarias en sus propias tablas . He hecho ambas cosas, si no me equivoco. ¿Alguna otra ayuda que ustedes puedan ofrecer?
Executing SQL script in server
ERROR: Error 1215: Cannot add foreign key constraint
-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
`Clients_Case_Number` INT NOT NULL ,
`Staff_Emp_ID` INT NOT NULL ,
PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
CONSTRAINT `fk_Clients_has_Staff_Clients`
FOREIGN KEY (`Clients_Case_Number` )
REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Clients_has_Staff_Staff1`
FOREIGN KEY (`Staff_Emp_ID` )
REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Ejecución de la secuencia de comandos SQL finalizada: instrucciones: 7 logradas, 1 falla
Aquí está el SQL para las tablas padre.
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
`Case_Number` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
`Address` CHAR(50) NULL ,
`Phone_Number` INT(10) NULL ,
PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
`Emp_ID` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB
Compruebe la compatibilidad de la mesa. Por ejemplo, si una tabla es MyISAM
y la otra es InnoDB
, puede tener este problema.
Cuando se produce este error porque la tabla a la que se hace referencia usa el motor MyISAM, esta respuesta proporciona una forma rápida de convertir su base de datos, por lo que todas las tablas modelo de Django usan InnoDB: https://.com/a/15389961/2950621
Es un comando de gestión de Django llamado convert_to_innodb.
El error 1215 es molesto. La respuesta de Explosion Pill cubre lo básico. Quieres asegurarte de empezar desde allí. Sin embargo, hay más casos, mucho más sutiles a tener en cuenta:
Por ejemplo, cuando intenta vincular CLAVES PRINCIPALES de diferentes tablas, asegúrese de proporcionar las opciones correctas de ON UPDATE
Y ON DELETE
. P.ej:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
no volará, porque las CLAVES PRIMARIAS (como id
) no pueden ser NULL
.
Estoy seguro de que hay más problemas, igualmente sutiles, al agregar este tipo de restricciones, razón por la cual al enfrentar errores de restricción, siempre asegúrese de que las restricciones y sus implicaciones tengan sentido en su contexto actual. Buena suerte con tu error 1215!
En mi caso tuve que deshabilitar las comprobaciones de FOREIGN KEY
ya que las tablas de origen no existían.
SET FOREIGN_KEY_CHECKS=0;
En mi caso, SET FOREIGN_KEY_CHECKS=0
una tabla usando SET FOREIGN_KEY_CHECKS=0
, luego SET FOREIGN_KEY_CHECKS=1
después. Cuando fui a recargar la tabla, obtuve el error 1215
. El problema era que había otra tabla en la base de datos que tenía una clave externa a la tabla que había eliminado y se estaba recargando. Parte del proceso de recarga implicó cambiar un tipo de datos para uno de los campos, lo que hizo que la clave foránea de la otra tabla no fuera válida, lo que provocó el error 1215
. Resolví el problema eliminando y luego volviendo a cargar la otra tabla con el nuevo tipo de datos para el campo involucrado.
Esta es una versión sutil de lo que ya se ha dicho, pero en mi caso, tuve 2 bases de datos (foo y bar). Primero creé foo y no me di cuenta de que hacía referencia a una clave externa en bar.baz (que aún no estaba creada). Cuando intenté crear bar.baz (sin ninguna clave externa), seguí recibiendo este error. Después de mirar alrededor por un rato encontré la clave foránea en foo.
Por lo tanto, en pocas palabras, si recibe este error, es posible que tenga una clave externa preexistente para la tabla que se está creando.
Esto también sucede cuando el tipo de las columnas no es el mismo.
por ejemplo, si la columna a la que se refiere es UNSIGNED INT y la columna a la que se hace referencia es INT, obtendrá este error.
Experimenté este error por una razón completamente diferente. Utilicé MySQL Workbench 6.3 para crear mi modelo de datos (herramienta impresionante). Noté que cuando el orden de columna definido en la definición de la restricción de clave externa no se ajusta a la secuencia de la columna de la tabla, también se genera este error.
Me tomó cerca de 4 horas de intentar todo lo demás, pero comprobar eso.
Ahora todo funciona bien y puedo volver a programar. :-)
Hay un error que he experimentado con el "Error 1215: No se puede agregar una restricción de clave externa" al usar Laravel 4, especialmente con los generadores Laravel 4 de JeffreyWay.
En Laravel 4, puede usar los generadores de JeffreyWay para generar archivos de migración para crear tablas una por una, lo que significa que cada archivo de migración genera una tabla. Debe tener en cuenta el hecho de que cada archivo de migración se genera con una marca de tiempo en el nombre de archivo, lo que le da un orden a los archivos. El orden de generación es también el orden de la operación de migración cuando se ejecuta el comando CLI de Artisan "php artisan migrate". Por lo tanto, si un archivo solicita una restricción de clave externa que se refiera a una clave que se generará en un último archivo, pero aún no se ha generado, se disparará el Error 1215. En tal caso, lo que debe hacer es ajustar el orden de generación de los archivos de migración. Genere nuevos archivos en el orden correcto, copie el contenido y luego elimine los archivos antiguos desordenados.
Incluso yo tuve el mismo problema. Y la falla fue con el marcador "sin firmar" en la tabla PK de FK
No puedo encontrar este error
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
Obtuve el mismo error al intentar agregar un fk. En mi caso, el problema fue causado por la PK de la tabla FK que se marcó como sin firmar.
Otra fuente de este error es que tiene 2 o más nombres de tablas iguales que tienen los mismos nombres de clave externa. Esto a veces le sucede a las personas que usan software de modelado y diseño, como Mysql Workbench, y luego generan el script desde el diseño.
Otra razón: si usa ON DELETE SET NULL
todas las columnas que se usan en la clave externa deben permitir valores nulos. Alguien más lo descubrió en esta pregunta .
A mi entender, no sería un problema relacionado con la integridad de los datos, pero parece que MySQL simplemente no admite esta función (en 5.7).
Para MySQL (INNODB) ... obtenga definiciones para las columnas que desea vincular
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name'',''referenced_table_name'') AND
COLUMN_NAME IN (''col_name'',''referenced_col_name'')/G
comparar y verificar que ambas definiciones de columna tienen
el mismo COLUMN_TYPE (longitud), el mismo COLATION
podría ser útil jugar como
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
Para mi fueron los tipos de columna. BigINT! = INT.
Pero entonces todavía no funcionó.
Así que revisé los motores. Asegúrese de que Table1 = InnoDB y Table = InnoDB
Para otros, el mismo error no siempre se debe a la falta de coincidencia de tipo de columna, puede encontrar más información acerca de un error de la clave de inicio de mysql emitiendo el comando
SHOW ENGINE INNODB STATUS;
puede encontrar un error cerca de la parte superior del mensaje impreso algo como
No se puede encontrar un índice en la tabla de referencia donde las columnas de referencia aparecen como las primeras columnas, o los tipos de columna en la tabla y la tabla de referencia no coinciden con la restricción.
Razones por las que puede obtener un error de restricción de clave externa:
- No está utilizando InnoDB como motor en todas las tablas.
- Está intentando hacer referencia a una clave inexistente en la tabla de destino. Asegúrese de que sea una clave en la otra tabla (puede ser una clave principal o única)
- Los tipos de columnas no son los mismos (la excepción es la columna en la tabla de referencia puede ser anulable).
- Si el PK / FK es un varchar, asegúrese de que la intercalación sea la misma para ambos.
Actualizar:
- Una de las razones puede ser que la columna que está utilizando para
ON DELETE SET NULL
no esté definida como nula. Así que asegúrese de que la columna esté configurada como nula por defecto.
Compruebe estos.
Sé que estoy muy tarde para la fiesta, pero quiero ponerlo aquí para que esté en la lista.
Además de todos los consejos anteriores para asegurarse de que los campos estén definidos de manera idéntica, y los tipos de tablas también tienen la misma intercalación, asegúrese de no cometer el error de novato al tratar de vincular campos donde los datos en el campo NIÑO no son Ya en el campo PADRES. Si tiene datos en el campo NIÑO que aún no ha ingresado en el campo PADRE, esto causará este error. Es una pena que el mensaje de error no sea un poco más útil.
Si no está seguro, haga una copia de seguridad de la tabla que tiene la clave externa, elimine todos los datos y luego intente crear la clave externa. Si tiene éxito entonces usted qué hacer!
Buena suerte.
Solo quería agregar este caso también para la relación de clave externa VARCHAR
. Pasé la última semana tratando de resolver esto en MySQL Workbench 8.0 y finalmente pude arreglar el error.
Respuesta corta: El conjunto de caracteres y la intercalación del esquema, la tabla, la columna, la tabla de referencia, la columna de referencia y cualquier otra tabla que haga referencia a la tabla principal deben coincidir.
Respuesta larga: tenía un tipo de datos ENUM en mi tabla. Cambié esto a VARCHAR
y puedo obtener los valores de una tabla de referencia para no tener que modificar la tabla principal para agregar opciones adicionales. Esta relación de clave externa parecía sencilla pero obtuve 1215 errores. La respuesta de arvind y el siguiente link sugirieron el uso de
SHOW ENGINE INNODB STATUS;
Al usar este comando obtuve la siguiente descripción detallada del error sin información adicional útil
No se puede encontrar un índice en la tabla de referencia donde las columnas de referencia aparecen como las primeras columnas, o los tipos de columna en la tabla y la tabla de referencia no coinciden con la restricción. Tenga en cuenta que el tipo de almacenamiento interno ENUM y SET cambió en las tablas creadas con> = InnoDB-4.1.12, y las columnas de estas tablas en las tablas nuevas no pueden hacer referencia a tales columnas en tablas antiguas. Consulte http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html para obtener la definición correcta de la clave externa.
Después de lo cual utilicé SET FOREIGN_KEY_CHECKS=0;
según lo sugerido por Arvind Bharadwaj y el enlace here :
Esto dio el siguiente mensaje de error:
Código de error: 1822. Error al agregar la restricción de clave externa. Falta el índice de restricción
En este punto, hice una ingeniería inversa del esquema y pude establecer la relación de clave externa en el diagrama EER. En "ingeniería directa", recibí el siguiente error:
Error 1452: no se puede agregar o actualizar una fila secundaria: falla una restricción de clave externa
Cuando reenvío el diagrama EER a un nuevo esquema, el script SQL se ejecutó sin problemas. Al comparar el SQL generado de los intentos de ingeniero de reenvío, encontré que la diferencia era el conjunto de caracteres y la intercalación. La tabla principal, la tabla secundaria y las dos columnas tenían utf8mb4
conjunto de caracteres utf8mb4
y una utf8mb4_0900_ai_ci
; sin embargo, se hizo referencia a otra columna en la tabla principal utilizando CHARACTER SET = utf8 , COLLATE = utf8_bin ;
a una mesa infantil diferente.
Para el esquema completo, cambié el conjunto de caracteres y la intercalación de todas las tablas y todas las columnas a lo siguiente:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
Esto finalmente resolvió mi problema con 1215 error.
Nota al utf8mb4_general_ci
: la intercalación utf8mb4_general_ci
funciona en MySQL Workbench 5.0 o posterior. La utf8mb4_0900_ai_ci
funciona solo para MySQL Workbench 8.0 o superior. Creo que una de las razones por las que tuve problemas con el conjunto de caracteres y la intercalación se debe a la actualización de MySQL Workbench a 8.0 en el medio. Aquí hay un link que habla más sobre esta colación.
Supongo que Clients.Case_Number
y / o Staff.Emp_ID
no son exactamente el mismo tipo de datos que Clients_has_Staff.Clients_Case_Number
y Clients_has_Staff.Staff_Emp_ID
.
Tal vez las columnas en las tablas de los padres son INT UNSIGNED
?
Deben ser exactamente el mismo tipo de datos en ambas tablas.
Tenga en cuenta el uso de backquotes también. Tenía en un guión la siguiente declaración
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
Pero las cotizaciones al final fueron falsas. Debería haber sido:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL da desafortunadamente no hay detalles sobre este error ...
Tuve el mismo error una vez. Simplemente reinicié el servidor MySQL y solucioné el problema.
Tuve el mismo problema, mi solución:
Antes de:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solución:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);
Espero que sea de ayuda;)
Verifique la intercalación de la tabla. Usando SHOW TABLE STATUS
, puede verificar información sobre las tablas, incluida la intercalación.
Ambas tablas tienen que tener la misma colación.
Me ha pasado
Wooo lo acabo de conseguir! Fue una mezcla de muchas respuestas ya publicadas (ennoDB, sin firmar, etc.). Sin embargo, una cosa que no vi aquí es: si su FK apunta a un PK, asegúrese de que la columna de origen tenga un valor que tenga sentido. Por ejemplo, si la PK es un mediumint (8), asegúrese de que la columna de origen también contenga un mediumint (8). Eso fue parte del problema para mí.
Yo tuve el mismo problema.
Lo resolví haciendo esto:
Creé la siguiente línea en el
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)
Descubrí esta solución después de intentar importar una tabla en mi generador de esquemas. Si funciona para usted, hágamelo saber!
¡Buena suerte!
Felipe Tércio
cuando se trata de hacer una clave externa cuando se utiliza la migración de laravel
como este ejemplo:
tabla de usuario
public function up()
{
Schema::create(''flights'', function (Blueprint $table) {
$table->increments(''id'');
$table->string(''name'');
$table->TinyInteger(''color_id'')->unsigned();
$table->foreign(''color_id'')->references(''id'')->on(''colors'');
$table->timestamps();
});
}
tabla de colores
public function up()
{
Schema::create(''flights'', function (Blueprint $table) {
$table->increments(''id'');
$table->string(''color'');
$table->timestamps();
});
}
a veces las propiedades no funcionaban
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
este error ocurrió porque la clave externa (tipo) en [tabla de usuario] es diferente de la clave principal (tipo) en [tabla de colores]
Para resolver este problema debe cambiar la clave principal en [tabla de colores]
$table->tinyIncrements(''id'');
Cuando usa la clave primaria $table->Increments(''id'');
Deberías usar Integer
como clave externa.
$table-> unsignedInteger(''fk_id'');
$table->foreign(''fk_id'')->references(''id'')->on(''table_name'');
Cuando usa la clave principal $table->tinyIncrements(''id'');
debe usar unsignedTinyInteger
como clave externa
$table-> unsignedTinyInteger(''fk_id'');
$table->foreign(''fk_id'')->references(''id'')->on(''table_name'');
Cuando usas la clave primaria $table->smallIncrements(''id'');
debe usar unsignedSmallInteger
como una clave externa
$table-> unsignedSmallInteger(''fk_id'');
$table->foreign(''fk_id'')->references(''id'')->on(''table_name'');
Cuando usa la clave principal $table->mediumIncrements(''id'');
Debería usar unsignedMediumInteger
como clave externa.
$table-> unsignedMediumInteger(''fk_id'');
$table->foreign(''fk_id'')->references(''id'')->on(''table_name'');