Postgres: Comment faire des clés composites?

Je ne peux pas comprendre l’erreur de syntaxe lors de la création d’une clé composite. C’est peut-être une erreur de logique, car j’ai testé de nombreuses variétés.

Comment créez-vous des clés composites dans Postgres?

CREATE TABLE tags ( (question_id, tag_id) NOT NULL, 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 no_duplicate_tag UNIQUE (question_id, tag_id) ); ERROR: syntax error at or near "(" LINE 3: (question_id, tag_id) NOT NULL, ^ 

Votre spécification PRIMARY KEY composée fait déjà ce que vous voulez. Omettez la ligne qui vous donne une erreur de syntaxe, et omettez également la clause CONSTRAINT redondante (déjà implicite):

  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) 

L’erreur que vous obtenez est à la ligne 3. c’est à dire qu’il n’est pas dans

 CONSTRAINT no_duplicate_tag UNIQUE (question_id, tag_id) 

mais plus tôt:

 CREATE TABLE tags ( (question_id, tag_id) NOT NULL, 

Je n’ai absolument aucune idée de la raison pour laquelle vous l’avez mise – quel est le but? quelle est la logique?

En tous cas. La définition correcte de la table est similaire à celle du pilcrow.

Et si vous voulez append un élément unique sur tag1, tag2, tag3 (ce qui semble très suspect), la syntaxe est la suivante:

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

ou, si vous voulez avoir la contrainte nommée selon votre souhait:

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