问题
Just curious, if I have this table:
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")
);
to store posts, and this table:
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")
);
and I want my post_id
field to point to post(id)
, how do I do it? I have tried with the following phrase:
"post_id" INTEGER NOT NULL UNIQUE,
REFERENCES "post" ("id") MATCH SIMPLE
ON UPDATE RESTRICT
ON DELETE RESTRICT,
but I am getting this error:
ERROR: there is no unique constraint matching given keys for referenced table "post"
The values of post_state(asembly_seat_id)
do not change in this case.
回答1:
A foreign key constraint can span multiple columns. You could just add the column revision
to the table 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)
);
Read the manual about foreign key constraints.
I am using the name post_id
for the primary key column of table post
. Don't use id
as column name. If you join a bunch of tables you end up with a bunch of columns all names id
. Regrettably, some half-wit ORMs are in the habit of doing that.
Alternatively, it might be better design to have unique post_id
in table post
and add a table post_revision
with a n:1 relation to post
.
来源:https://stackoverflow.com/questions/16462098/foreign-key-matching-in-postgresql