sql >> Base de Datos >  >> RDS >> Mysql

MySQL Creando tablas con Foreign Keys dando errno:150

Tuve el mismo problema con ALTER TABLE ADD FOREIGN KEY .

Después de una hora, descubrí que se deben cumplir estas condiciones para no recibir el error 150:

  1. La tabla principal debe existir antes de definir una clave externa para hacer referencia a ella. Debe definir las tablas en el orden correcto:la tabla principal primero, luego la tabla secundaria. Si ambas tablas se referencian entre sí, debe crear una tabla sin restricciones FK, luego crear la segunda tabla y luego agregar la restricción FK a la primera tabla con ALTER TABLE .

  2. Las dos tablas deben admitir restricciones de clave externa, es decir, ENGINE=InnoDB . Otros motores de almacenamiento ignoran silenciosamente las definiciones de claves foráneas, por lo que no devuelven ningún error ni advertencia, pero la restricción FK no se guarda.

  3. Las columnas a las que se hace referencia en la tabla principal deben ser las columnas más a la izquierda de una clave. Mejor si la clave en el Padre es PRIMARY KEY o UNIQUE KEY .

  4. La definición de FK debe hacer referencia a la(s) columna(s) PK en el mismo orden que la definición de PK. Por ejemplo, si FK REFERENCES Parent(a,b,c) entonces el PK del padre no debe definirse en las columnas en orden (a,c,b) .

  5. Las columnas PK de la tabla principal deben tener el mismo tipo de datos que las columnas FK de la tabla secundaria. Por ejemplo, si una columna PK en la tabla principal es UNSIGNED , asegúrese de definir UNSIGNED para la columna correspondiente en el campo de la tabla secundaria.

    Excepción:la longitud de las cadenas puede ser diferente. Por ejemplo, VARCHAR(10) puede hacer referencia a VARCHAR(20) o viceversa.

  6. Cualquier columna(s) FK de tipo cadena debe tener el mismo juego de caracteres y la misma clasificación que la(s) columna(s) PK correspondiente(s).

  7. Si ya hay datos en la tabla secundaria, cada valor en la(s) columna(s) FK debe coincidir con un valor en la(s) columna(s) PK de la tabla principal. Compruébalo con una consulta como:

    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    Esto debe devolver cero (0) valores no coincidentes. Obviamente, esta consulta es un ejemplo genérico; debe sustituir los nombres de sus tablas y columnas.

  8. Ni la tabla principal ni la tabla secundaria pueden ser TEMPORARY mesa.

  9. Ni la tabla principal ni la tabla secundaria pueden ser PARTITIONED mesa.

  10. Si declara un FK con ON DELETE SET NULL opción, entonces la(s) columna(s) FK deben ser anulables.

  11. Si declara un nombre de restricción para una clave externa, el nombre de la restricción debe ser único en todo el esquema, no solo en la tabla en la que se define la restricción. Es posible que dos tablas no tengan su propia restricción con el mismo nombre.

  12. Si hay otros FK en otras tablas que apuntan al mismo campo para el que está intentando crear el nuevo FK, y tienen un formato incorrecto (es decir, una intercalación diferente), primero deberán ser consistentes. Esto puede ser el resultado de cambios anteriores donde SET FOREIGN_KEY_CHECKS = 0; se utilizó con una relación inconsistente definida por error. Consulte la respuesta de @andrewdotn a continuación para obtener instrucciones sobre cómo identificar estos problemas de FK.

Espero que esto ayude.