1

Просто интересно, если у меня есть эта таблица:ключ иностранных паросочетание в PostgreSQL

CREATE TABLE "post" (
    "id" SERIAL, 
    "revision" INTEGER NOT NULL DEFAULT 0, 
    "summary" CHARACTER VARYING NOT NULL, 
    "description" TEXT NOT NULL, 
    "user_id" INTEGER NOT NULL 
     REFERENCES "user" ("id") MATCH FULL 
      ON UPDATE CASCADE 
      ON DELETE RESTRICT, 
    "post_type_id" INTEGER NOT NULL 
     REFERENCES "post_type" ("id") MATCH FULL 
      ON UPDATE CASCADE 
      ON DELETE RESTRICT, 
    "ctime" TIMESTAMP WITH TIME ZONE DEFAULT NOW(), 
    PRIMARY KEY("id", "revision") 
); 

хранить сообщения, и эту таблицу:

CREATE TABLE "post_state" (
    "post_id" INTEGER NOT NULL, 
    "assembly_seat_id" INTEGER NOT NULL 
     REFERENCES "assembly_seat" ("id") MATCH FULL 
      ON UPDATE CASCADE 
      ON DELETE RESTRICT, 
    PRIMARY KEY("post_id") 
); 

, и я хочу, чтобы мой post_id поле, чтобы указать на post(id), как мне это сделать? Я попытался следующей фразой:

"post_id" INTEGER NOT NULL UNIQUE, 
     REFERENCES "post" ("id") MATCH SIMPLE 
      ON UPDATE RESTRICT 
      ON DELETE RESTRICT, 

, но я получаю эту ошибку:

ERROR: there is no unique constraint matching given keys for referenced table "post"

Значения post_state(asembly_seat_id) не изменяются в этом случае.

+1

Вы можете создать только внешний ключ, который ссылается на одну строку в другой таблице. Поскольку 'post_id' не уникален (единственная комбинация post_id/revision уникальна), вы не можете ссылаться на нее. –

+0

ОН, спасибо за ответ, глупо меня * facepalm * – Jeffrey04

+0

@JoachimIsaksson: Вас может заинтересовать мой ответ, который противоречит вашим комментариям по частям. –

ответ

4

Ограничение внешнего ключа может охватывать несколько столбцов. Вы можете просто добавить столбец revision в таблицу post_state.

CREATE TEMP TABLE post (
    post_id serial NOT NULL 
,revision integer NOT NULL DEFAULT 0 
,summary text NOT NULL 
,description text NOT NULL 
,user_id integer NOT NULL 
    REFERENCES user (id) MATCH FULL ON UPDATE CASCADE ON DELETE RESTRICT 
,post_type_id integer NOT NULL 
    REFERENCES post_type (id) MATCH FULL ON UPDATE CASCADE ON DELETE RESTRICT 
,ctime timestamptz DEFAULT NOW() 
,PRIMARY KEY(post_id, revision) 
); 

CREATE TEMP TABLE post_state (
    post_id integer NOT NULL 
,revision integer NOT NULL 
,assembly_seat_id integer NOT NULL 
    REFERENCES assembly_seat (id) MATCH FULL ON UPDATE CASCADE ON DELETE RESTRICT 
,PRIMARY KEY(post_id, revision) 
,FOREIGN KEY (post_id, revision) REFERENCES post (post_id, revision) 
);

Прочтите руководство по эксплуатации foreign key constraints.

Я использую имя post_id для столбца первичного ключа таблицы post. Не используйте id в качестве имени столбца. Если вы присоединитесь к кучу таблиц, вы получите кучу столбцов всех имен id. К сожалению, у некоторых ORM с половиной остроумием есть привычка делать это.

С другой стороны, это может быть лучше дизайн иметь уникальный post_id в таблице post и добавить таблицу post_revision с п: 1 отношение к post.

+0

Отличный ответ. SQL легко: * как только вы освоите синтаксис, все сводится к проблеме моделирования данных. * – wildplasser

+0

@ Erwin yea, я на самом деле переработал модель и получил другую таблицу post_revision, как вы упомянули: P – Jeffrey04

Смежные вопросы