В дополнение к комментарию ceejayoz можно также использовать ActionMailer для ловли ответов, которые передают обратно, и действие на них - Вам будет нужна некоторая форма уникального идентификатора в месте, которое будет включено в ответ все же.
Спецификация вашего соединения PRIMARY KEY
уже выполняет то, что вы хотите. Опустите строку, которая дает вам синтаксическую ошибку, и опустите также повторяющееся ОГРАНИЧЕНИЕ
(уже подразумеваемое):
CREATE TABLE tags
(
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
tag3 VARCHAR(20),
PRIMARY KEY(question_id, tag_id)
);
NOTICE: CREATE TABLE will create implicit sequence "tags_tag_id_seq" for serial column "tags.tag_id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tags_pkey" for table "tags"
CREATE TABLE
pg=> \d tags
Table "public.tags"
Column | Type | Modifiers
-------------+-----------------------+-------------------------------------------------------
question_id | integer | not null
tag_id | integer | not null default nextval('tags_tag_id_seq'::regclass)
tag1 | character varying(20) |
tag2 | character varying(20) |
tag3 | character varying(20) |
Indexes:
"tags_pkey" PRIMARY KEY, btree (question_id, tag_id)
Ошибка, которую вы получаете, находится в строке 3. т.е. ее нет в
CONSTRAINT no_duplicate_tag UNIQUE (question_id, tag_id)
, а в более ранней версии:
CREATE TABLE tags
(
(question_id, tag_id) NOT NULL,
Правильное определение таблицы похоже на показанное в pilcrow.
И если вы хотите добавить уникальность к тегам tag1, tag2, tag3 (что звучит очень подозрительно), тогда используйте следующий синтаксис:
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
tag3 VARCHAR(20),
PRIMARY KEY(question_id, tag_id),
UNIQUE (tag1, tag2, tag3)
);
или, если вы хотите, чтобы ограничение было названо по вашему желанию:
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
tag3 VARCHAR(20),
PRIMARY KEY(question_id, tag_id),
CONSTRAINT some_name UNIQUE (tag1, tag2, tag3)
);