Postgres: Bagaimana cara melakukan kunci komposit?

111

Saya tidak dapat memahami kesalahan sintaks dalam membuat kunci komposit. Ini mungkin kesalahan logika, karena saya telah menguji banyak varietas.

Bagaimana Anda membuat kunci komposit di 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 준영
sumber

Jawaban:

171

PRIMARY KEYSpesifikasi gabungan Anda sudah memenuhi keinginan Anda. Abaikan baris yang memberi Anda kesalahan sintaks, dan hilangkan juga redundan CONSTRAINT(sudah tersirat):

 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
sumber
Bagaimana Anda akan menerapkan pembatas seperti "CONSTRAINT no_duplicate_refences REFERENSI UNIK DARI tag_id TO (tag1, tag2, tag3)"?
Léo Léopold Hertz 준영
4
@ Masi, saya rasa saya tidak cukup memahami apa yang Anda coba modelkan di sini, dan, sejujurnya, kolom tag1melalui tag3menyarankan kepada saya bahwa Anda mungkin harus melakukan perbaikan desain lebih lanjut. Mungkin pertanyaan terpisah, dengan deskripsi bahasa alami dari model Anda dan beberapa rekaman contoh, akan membantu.
pilcrow
18

Kesalahan yang Anda dapatkan ada di baris 3. yaitu tidak masuk

CONSTRAINT no_duplicate_tag UNIQUE (question_id, tag_id)

tapi sebelumnya:

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

Definisi tabel yang benar seperti yang ditunjukkan oleh pilcrow.

Dan jika ingin menambahkan unique pada tag1, tag2, tag3 (yang terdengar sangat mencurigakan), maka sintaksnya adalah:

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

atau, jika Anda ingin diberi nama kendala sesuai keinginan Anda:

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
sumber