2011-02-16 36 views
10

Estoy intentando crear una clave externa en dos columnas de una tabla para apuntar a la misma columna de otra tabla, pero parecen tener un error ...Adición de clave externa en varias columnas

Esto es lo yo:

CREATE TABLE test2 (
    ID INT NOT NULL AUTO_INCREMENT, 
    col1 INT NOT NULL, 
    col2 INT NOT NULL, 
    PRIMARY KEY (ID), 
    CONSTRAINT fk FOREIGN KEY (col1, col2) 
       REFERENCES test1(ID, ID) 
    ON UPDATE CASCADE 
    ON DELETE RESTRICT 
) ENGINE=InnoDB; 

pero me da

ERROR 1005 (HY000): Can't create table 'DB.test2' (errno: 150)

Si sólo tengo una columna, sin embargo, la tabla se crea correctamente.

¿Podría alguien indicarme dónde está el error?

Gracias n

+0

¿Qué es DDL of test1? – Chandu

+0

@Cybernate: lo siento, se olvidó de especificar, ID es la clave principal de test1, con el mismo tipo que col1 y col2 (INT). Hay muchas otras columnas (pero eso no debería importar) Y no se establecen otras restricciones o índices. – nico

+0

¿Ha intentado esto sin especificar actualizaciones o eliminaciones en cascada? – Thomas

Respuesta

8

Probamos aquí y consiguieron el mismo error. Esto funciona sin embargo:

CREATE TABLE test2 (
    ID INT NOT NULL AUTO_INCREMENT, 
    col1 INT NOT NULL, 
    col2 INT NOT NULL, 
    PRIMARY KEY (ID), 
    CONSTRAINT fk FOREIGN KEY (col1) 
       REFERENCES test1(ID) 
    ON UPDATE CASCADE 
    ON DELETE RESTRICT, 
    CONSTRAINT fk2 FOREIGN KEY (col2) 
       REFERENCES test1(ID) 
    ON UPDATE CASCADE 
    ON DELETE RESTRICT 

) ENGINE=InnoDB 

Sí, lo sé - la secuencia de comandos debe trabajo (aunque no parece tener mucho sentido). Sin embargo, creo que esta nueva versión es mejor.

+0

Bueno, funciona. No estoy seguro de por qué el mío no pero, de todos modos ... – nico

+4

@nico - Funciona porque tienes dos relaciones independientes con la misma columna de la tabla padre. Piénselo de esta manera, solo si la clave de la tabla padre fuera una clave de varias columnas, ¿usaría la sintaxis que tiene en su publicación original? Si la columna de la tabla principal es una sola columna, para cada columna secundaria desea hacer referencia a esa columna de tabla principal, debe crear una restricción de clave externa separada. – Thomas

+0

@Thomas: Ok, ahora lo entiendo! En efecto, al pensarlo, tiene mucho sentido. Gracias. – nico

2

El problema parece ser que está especificando la misma columna principal dos veces en la misma clave externa (es decir, (ID, ID)). El siguiente debería funcionar:

Create Table Test1 
    (
    PK1 int not null 
    , PK2 int not null 
    , Primary Key (PK1, PK2) 
    ) 

Create Table Test2 
    (
    Id int not null Auto_Increment 
    , PK1 int not null 
    , PK2 int not null 
    , Primary Key (ID) 
    , Constraint FK_Test2 
     Foreign Key (PK1, PK2) 
     References Test1(PK1, PK2) 
    ) 

Si es el caso, que desea dos columnas en una tabla secundaria que hacen referencia a la misma columna de la tabla padre, entonces debe agregar dos referencias de clave externa como se muestra por rsenna como los que representan dos relaciones independientes.

+0

Bueno, pero no tengo una clave primaria compuesta en Test1 ... ambas columnas en Test2 deberían apuntar a la misma clave primaria (única) en Test1. – nico

+0

@nico - Entonces esos representan dos relaciones independientes y requieren dos restricciones de clave externa. Solo usaría la sintaxis que tiene en su PO cuando la columna principal es una clave de varias columnas. – Thomas

Cuestiones relacionadas