Postgres: Jak zrobić klucze złożone?

112

Nie mogę zrozumieć błędu składni podczas tworzenia klucza złożonego. Może to być błąd logiczny, ponieważ przetestowałem wiele odmian.

Jak tworzyć klucze złożone w 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,
                          ^
Léo Léopold Hertz 준영
źródło

Odpowiedzi:

173

Twoja PRIMARY KEYspecyfikacja złożona już robi to, czego chcesz. Pomiń wiersz, który powoduje błąd składniowy, i pomiń także nadmiarowy CONSTRAINT(już dorozumiany):

 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)
pilcrow
źródło
W jaki sposób można zaimplementować ograniczenie typu „CONSTRAINT no_duplicate_refences UNIQUE REFERENCE FROM tag_id TO (tag1, tag2, tag3)”?
Léo Léopold Hertz 준영
4
@Masi, nie sądzę Rozumiem tyle, co starasz się modelować tutaj, i, szczerze mówiąc, kolumny tag1przez tag3sugerują mi się, że może mieć dalsze udoskonalenia konstrukcyjne do zrobienia. Być może pomocne byłoby oddzielne pytanie, z opisem twojego modelu w języku naturalnym i kilkoma przykładowymi zapisami.
pilcrow
18

Błąd, który otrzymujesz, znajduje się w linii 3., tj. Go nie ma

CONSTRAINT no_duplicate_tag UNIQUE (question_id, tag_id)

ale wcześniej:

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

Prawidłowa definicja tabeli jest taka, jak pokazał Pilcrow.

A jeśli chcesz dodać unikalny do tag1, tag2, tag3 (co brzmi bardzo podejrzanie), składnia jest następująca:

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

lub, jeśli chcesz, aby ograniczenie zostało nazwane zgodnie z Twoim życzeniem:

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)
);
Jon Bates
źródło