Postgres contrainte unique vs indice de
Que je peux comprendre la documentation les définitions suivantes sont équivalentes:
create table foo (
id serial primary key,
code integer,
label text,
constraint foo_uq unique (code, label));
create table foo (
id serial primary key,
code integer,
label text);
create unique index foo_idx on foo using btree (code, label);
Cependant vous pouvez le lire dans la note de: La meilleure façon d'ajouter une contrainte unique à une table ALTER TABLE ... AJOUTER la CONTRAINTE. L'utilisation des index pour faire respecter les contraintes unique peut être considéré comme un détail d'implémentation qui ne doivent pas être accessibles directement.
Est-ce seulement une question de style? Quelles sont les conséquences pratiques de choix de l'une de ces variantes (par exemple, dans la performance)?
- Le (seul) pratique, la différence est que vous pouvez créer une clé étrangère à une contrainte unique, mais pas à un index unique.
- Un avantage dans l'autre sens (comme venu d'une autre question récemment), c'est que vous pouvez avoir partielle d'un index unique, comme "Unique" ( foo ) bar Où Est Nulle". Autant que je sache, il n'y a pas moyen de le faire avec une contrainte.
- Je ne suis pas sûr quand c'est arrivé, mais cela ne semble plus être vrai. Ce SQL violon permet de clé étrangère des références à un index unique: sqlfiddle.com/#!17/20ee9; EDIT: ajout d'un "filtre" à l'index unique causes de cet arrêt de travail (comme prévu)
- de postgres documentation: PostgreSQL crée automatiquement un index unique lorsqu'une contrainte unique ou de clé primaire est définie pour une table. postgresql.org/docs/9.4/static/indexes-unique.html
- Je suis d'accord avec @user1935361, si ce n'était pas possible de créer une clé étrangère d'un index unique (avec PG 10 au moins), j'aurais rencontré ce problème il y a longtemps.
- postgres liste de diffusion de réponse
Vous devez vous connecter pour publier un commentaire.
J'ai eu quelques doutes sur cette base, mais la question importante, j'ai donc décidé d'apprendre par l'exemple.
Let's create table test maître avec deux colonnes, con_id avec contrainte unique et ind_id indexées par l'index unique.
Dans la description de la table (\d dans psql) vous pouvez dire de la contrainte unique à partir de l'index unique.
Unicité
Nous allons vérifier l'unicité, juste au cas où.
Qu'il fonctionne comme prévu!
Clés étrangères
Maintenant, nous allons définir détail table avec deux clés étrangères de référencement pour nos deux colonnes dans maître.
Bien, pas d'erreurs. Faisons en sorte que cela fonctionne.
Les deux colonnes peuvent être référencées dans les clés étrangères.
Contrainte à l'aide de l'indice de
Vous pouvez ajouter la contrainte de table en utilisant les index unique.
Maintenant il n'y a pas de différence entre les contraintes de colonne description.
Partielle index
Dans le tableau contrainte de déclaration vous ne pouvez pas créer partielle index.
Il vient directement de la définition de
create table ...
.Dans l'index unique de déclaration, vous pouvez définir
WHERE clause
de créer des index partiel.Vous pouvez également créer des index sur l'expression (pas seulement sur la colonne) et définir d'autres paramètres (classement, l'ordre de tri, les valeurs Null de placement).
Vous ne pouvez pas ajouter contrainte de table à l'aide partielle de l'indice.
Un autre avantage de l'utilisation de
UNIQUE INDEX
vsUNIQUE CONSTRAINT
est que vous pouvez facilementDROP
/CREATE
un indexSIMULTANÉMENT
, alors qu'avec une contrainte, vous ne pouvez pas.Le texte intégral
Donc, la vitesse de la performance doit être la même
Une autre chose que j'ai rencontré est que vous pouvez utiliser des expressions sql dans les index uniques, mais pas dans les contraintes.
Donc, cela ne fonctionne pas:
mais suite à des travaux.
citext
extension.J'ai lu cela dans la doc:
Donc je pense que c'est ce que vous appelez "partielle de l'unicité" par l'ajout d'une contrainte.
Et, sur la façon de garantir l'unicité:
Donc, nous devrions ajouter des contraintes, ce qui crée un index, afin d'assurer l'unicité.
Comment je vois ce problème?
Une "contrainte" vise à gramatically en sorte que cette colonne doit être unique, il établit une loi, une règle; alors que la "index" est semantical, sur "comment mettre en œuvre, comment faire pour obtenir l'unicité, ce qui ne l'unique moyen de quand il s'agit de la mise en œuvre". Ainsi, la manière de Postgresql met en œuvre, c'est très logique: tout d'abord, vous déclarez que la colonne doit être unique, alors, Postgresql ajoute la mise en œuvre de l'ajout d'un index unique pour vous.
Il y a une différence dans le verrouillage.
L'ajout d'un index ne bloque pas l'accès en lecture à la table.
L'ajout d'une contrainte de placer un verrou de table (tous les sélectionne sont bloqués) depuis il est ajouté via ALTER TABLE.