2011-10-05 8 views
12

MySQL 5.1.59 genera un error de error con esta tabla crear:¿Qué pasa con la restricción de clave externa en esta tabla

CREATE TABLE IF NOT EXISTS `genre` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `abv` CHAR(3) CHARACTER SET 'latin1' COLLATE 'latin1_bin' NULL DEFAULT NULL , 
    `name` VARCHAR(80) NOT NULL DEFAULT '' , 
    `parent_id` INT NULL DEFAULT NULL , 
    PRIMARY KEY (`id`) , 
    INDEX `fk_genre_genre1` (`parent_id` ASC) , 
    CONSTRAINT `fk_genre_genre1` 
    FOREIGN KEY (`parent_id`) 
    REFERENCES `genre` (`id`) 
    ON DELETE SET NULL 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 

que se generó por MySQL Workbench 5.2.33.

El mensaje de error es:

ERROR 1005 (HY000) at line __: Can't create table 'mydb.genre' (errno: 150) 

Qué le pasa a esta tabla crear?

The manual says:

si MySQL reporta un número de error 1005 de una sentencia CREATE TABLE, y el mensaje de error se refiere al error 150, la creación de tablas fallidos debido a una restricción de clave externa no se formó correctamente.

También dice que las referencias de clave externa a la misma mesa están permitidos:

InnoDB soporta referencias de clave externa dentro de una tabla. En estos casos, "registros de tabla hijo" realmente se refiere a registros dependientes dentro de la misma tabla .

La relación que deseo es un elemento primario no identificable para representar una jerarquía de géneros y subgéneros. Un género no tiene que tener un padre, por lo tanto parent_id es nulo.

Puede ser relevante que MySQL Workbench establece lo siguiente:

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 
+2

'MOSTRAR ENGINE InnoDB STATUS' inmediatamente después de recibir ese error. Le dará el mensaje de error real, normalmente. – derobert

+1

+1 Para una pregunta bellamente formateada con toda la información relevante. – Johan

+0

Esa es una sugerencia útil, derobert, gracias! –

Respuesta

8

Su columna id es int unsigned; su columna parent_id es int. Esos no coinciden. La solución es cambiar parent_id para que sea int unsigned también.

Si ejecuta el SHOW ENGINE InnoDB STATUS puse en un comentario, ve esto:

11005 17:18:38 Error in foreign key constraint of table test/genre: 

    FOREIGN KEY (`parent_id`) 
    REFERENCES `genre` (`id`) 
    ON DELETE SET NULL 
    ON UPDATE CASCADE) 
ENGINE = InnoDB: 
Cannot find an index in the referenced table where the 
referenced columns appear as the first columns, or column types 
in the table and the referenced table do not match for constraint. 
Note that the internal storage type of ENUM and SET changed in 
tables created with >= InnoDB-4.1.12, and such columns in old tables 
cannot be referenced by such columns in new tables. 
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html 
for correct foreign key definition. 

Nota los "tipos de columna de la tabla y la tabla de referencia no coinciden" parte.

+0

¡Bueno, eso es una solución fácil! Gracias. –

+0

+1 para la salida del motor de muestra. – Johan

+0

gracias! salvó mi día – zeroliu

6

Los dos campos no son del mismo tipo.

CREATE TABLE IF NOT EXISTS `genre` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, <<-- unsigned int 
    .. 
    .. 
    `parent_id` INT NULL DEFAULT NULL ,  <<-- signed int 
    PRIMARY KEY (`id`) ,     ***** not the same!!!! 
    .... 
+0

¡Súper! ¡Gracias! Le di a Robert Robert la marca de verificación solo porque fue un minuto antes. –

+0

@fsb, ¡No lo fue! -) hace 16 minutos, derobert hace 15 minutos. Todavía derobert tenía un gran vínculo con el motor del show, por lo que su aceptación está bien ganada. – Johan

5

id es UNSIGNEDparent_id pero no tiene signo.

5

Los campos deben ser del mismo tipo. id no está firmado mientras parent_id no es

Cuestiones relacionadas