Postgres: Référence unique de A à B
-
18-09-2019 - |
Question
Je veux une bijection entre la paire (balise1, tag2) et tag_id.
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
PRIMARY KEY(question_id, tag_id),
(tag1, tag2) UNIQUE references tags(tag_id) #How?
);
Je ne veux pas référence tel que:
(PHP, Perl) points to 1 and 2,
3 points to (C#, null) and (Python, Elinks)
En d'autres termes, je veux que la référence soit unique à partir (balise1, tag2) TAGS (tag_id), pas UNIQUE (point1, tag2).
La solution
Cela pourrait être plus comme ce que vous cherchez:
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
PRIMARY KEY (tag_id),
INDEX (question_id),
UNIQUE (tag1, tag2)
);
Faire 'tag_id la clé primaire signifie que vous ne pouvez avoir une entrée avec une donnée « tag_id », et que les recherches basées sur « tag_id » sera rapide.
L'index sur « question_id » améliorera la vitesse de recherche basée sur « question_id », qui est ce que je pense que vous essayez de faire avec votre définition de la clé primaire d'origine. Si vous voulez vraiment le (tag_id, question_id) paire soit unique, comme vous l'aviez, puis ajoutez un UNIQUE (tag_id, question_id) là-bas, mais je dirais que vous devriez laisser tag_id comme clé primaire.
La contrainte d'unicité sur (tag1, tag2) empêche la mise en correspondance inverse d'avoir des doublons.
Voici quelques exemples de ce qui peut fonctionner:
Travaux:
1 -> (x, y)
2 -> (x, z)
Fails (tag_id est une clé primaire, et est donc unique):
1 -> (x, y)
1 -> (y, x)
échoue (la paire (tag1, tag2) est pas unique):
1 -> (x, y)
2 -> (x, y)
Cependant, la paire (x, y) est différent de la paire (y, x). Je ne suis pas sûr de savoir comment attraper cette contrainte d'unicité.