Postgres: Wie mache ich zusammengesetzte Schlüssel?

110

Ich kann den Syntaxfehler beim Erstellen eines zusammengesetzten Schlüssels nicht verstehen. Es kann ein logischer Fehler sein, weil ich viele Sorten getestet habe.

Wie erstellen Sie zusammengesetzte Schlüssel in 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 준영
quelle

Antworten:

170

Ihre zusammengesetzte PRIMARY KEYSpezifikation macht bereits, was Sie wollen. Lassen Sie die Zeile weg, die einen Syntaxfehler verursacht, und lassen Sie auch die redundante CONSTRAINT(bereits implizierte) Zeile weg :

 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)
Pilger
quelle
Wie würden Sie ein Contraint wie "CONSTRAINT no_duplicate_refences UNIQUE REFERENCE FROM tag_id TO (tag1, tag2, tag3)" implementieren?
Léo Léopold Hertz 준영
4
@Masi, ich glaube nicht, dass ich genug von dem verstehe, was Sie hier modellieren möchten, und um ehrlich zu sein, die tag1durchgehenden Spalten tag3deuten darauf hin, dass Sie möglicherweise weitere Designverbesserungen vornehmen müssen. Vielleicht hilft eine separate Frage mit einer Beschreibung Ihres Modells in natürlicher Sprache und einigen Beispieldatensätzen.
Pilcrow
18

Der Fehler, den Sie erhalten, steht in Zeile 3. Das heißt, er ist nicht in

CONSTRAINT no_duplicate_tag UNIQUE (question_id, tag_id)

aber früher:

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

Die korrekte Tabellendefinition entspricht der von Pilcrow.

Und wenn Sie Tag1, Tag2, Tag3 eindeutig hinzufügen möchten (was sehr verdächtig klingt), lautet die Syntax wie folgt:

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

oder, wenn Sie möchten, dass die Einschränkung gemäß Ihrem Wunsch benannt wird:

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
quelle