Postgres FK со ссылкой на композитный ПК - PullRequest
24 голосов
/ 03 апреля 2012

Рассмотрим

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)
);

Как мне создать FK в "bar", который ссылается на PK в "foo"?

Ответы [ 2 ]

35 голосов
/ 03 апреля 2012

Как мне создать FK в "bar", который ссылается на PK в "foo"?

С вашей текущей структурой вы не можете.

Цель ссылки на внешний ключ должна быть объявлена ​​либо PRIMARY KEY, либо UNIQUE.Так что либо

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

, либо

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

будет работать как цель для bar.foo_id.Тогда bar будет иметь простую ссылку.

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

Если вы хотите сослаться на первичный ключ, который вы первоначально объявили в foo, вы должны сохранить этот первичный ключ в bar.Вы должны хранить все это, а не часть этого.Так что, не изменяя foo, вы можете построить панель вот так.

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 (id, foo_created_on),
    PRIMARY KEY (id, bar_created_on)
);
17 голосов
/ 03 апреля 2012

Вы должны создать отдельные внешние ключи:

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)
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...