web-dev-qa-db-fra.com

Postgres: Comment faire des clés composites?

Je ne comprends pas 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 composé PRIMARY KEY spécification fait déjà ce que vous voulez. Omettez la ligne qui vous donne une erreur de syntaxe, ainsi que le redondant CONSTRAINT (déjà impliqué):

 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)
135
pilcrow

L’erreur que vous obtenez est dans la ligne 3. c’est-à-dire qu’elle 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,

La définition correcte de la table est comme l'a montré Pilcrow.

Et si vous souhaitez ajouter 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 souhaitez que la contrainte soit 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)
);
13
user80168