2012-04-02 15 views
11

ConsiderePostgres FK referencia PK compuesta

CREATE TABLE foo (
    id SERIAL, 
    foo_created_on ABSTIME, 
    foo_deactivated_on ABSTIME, 
    PRIMARY KEY (id, foo_created_on) 
); 

CREATE TABLE bar (
    id SERIAL, 
    bar_created_on ABSTIME, 
    bar_deactivated_on ABSTIME, 
    foo_id REFERENCES (.. what goes here? ..), 
    PRIMARY KEY (id, bar_created_on) 
); 

¿Cómo se crea una FK en el "bar" que hace referencia al PK en "foo"?

+2

BTn: el tipo de datos "ABSTIME" no se admite. Deberías usar DATE o TIMESTAMP en su lugar. –

Respuesta

8

Tienes que crear las claves externas separadas:

CREATE TABLE bar (
    id SERIAL, 
    bar_created_on ABSTIME, 
    bar_deactivated_on ABSTIME, 
    foo_id INT, 
    FOREIGN KEY (foo_id, created_on) REFERENCES foo (id, created_on), 
    PRIMARY KEY (id, bar_created_on) 
); 
+0

lo siento, no está claro ... (Debería haber dado los nombres distintivos de la columna "created_on" para desambiguar ... vea la pregunta actualizada ahora). ¿El encantamiento anterior está en el esquema de "barra"? Tenga en cuenta que bar's created_on tracks created_on para entradas de barra, no para entradas foo. – punkish

+0

He actualizado la respuesta. No sé para qué era tu foo_id, por lo tanto, simplemente lo hice un int. Las referencias son bastante fáciles, pero quizás no entiendo lo que quieres decir. –

18

¿Cómo se crea una FK en el "bar" que hace referencia al PK en "foo"?

Con su estructura actual, no puede.

El objetivo de una referencia de clave externa debe declararse PRIMARY KEY o UNIQUE. Así que, o este

CREATE TABLE foo (
    id SERIAL PRIMARY KEY, 
    foo_created_on ABSTIME, 
    foo_deactivated_on ABSTIME, 
    UNIQUE (id, foo_created_on) 
); 

o esta

CREATE TABLE foo (
    id SERIAL, 
    foo_created_on ABSTIME, 
    foo_deactivated_on ABSTIME, 
    PRIMARY KEY (id, foo_created_on), 
    UNIQUE (id) 
); 

funcionaría como un objetivo para bar.foo_id. Entonces la barra tendría una referencia simple.

CREATE TABLE bar (
    id SERIAL, 
    bar_created_on ABSTIME, 
    bar_deactivated_on ABSTIME, 
    foo_id REFERENCES foo (id), 
    PRIMARY KEY (id, bar_created_on) 
); 

Si desea hacer referencia a la clave primaria que declaró originalmente en foo, debe almacenar esa clave primaria en la barra. Tienes que almacenar todo, no parte de él. Entonces, sin modificar foo, podrías construir una barra como esta.

CREATE TABLE bar (
    id SERIAL, 
    bar_created_on ABSTIME, 
    bar_deactivated_on ABSTIME, 
    foo_id INTEGER NOT NULL, 
    foo_created_on ABSTIME NOT NULL, 
    FOREIGN KEY (foo_id, foo_created_on) REFERENCES foo (foo_id, foo_created_on), 
    PRIMARY KEY (id, bar_created_on) 
); 
Cuestiones relacionadas