web-dev-qa-db-fra.com

Clé primaire versus contrainte unique?

Je conçois actuellement une toute nouvelle base de données. À l'école, nous avons toujours appris à mettre une clé primaire dans chaque tableau.

J'ai lu beaucoup d'articles, de discussions et de newsgroups disant qu'il est préférable d'utiliser une contrainte unique (index unique pour certaines bases de données) plutôt que PK.

Quel est ton point de vue?

44
vIceBerg

Pouvez-vous fournir des références à ces articles?

Je ne vois aucune raison de changer les méthodes éprouvées. Après tout, les clés primaires sont une caractéristique fondamentale de la conception des bases de données relationnelles.

Utiliser UNIQUE pour atteindre le même objectif me semble vraiment ridicule. Quelle est leur raison?

Edit: Mon attention vient de revenir à cette ancienne réponse. Peut-être que la discussion que vous avez lue concernant PK vs. UNIQUE a concerné des personnes qui font de quelque chose une PK dans le seul but de lui imposer un caractère unique. La réponse à cette question est: Si IS est une clé, définissez-la clé, sinon définissez-la UNIQUE. 

38
Chris Cudmore

Une clé primaire est simplement une clé candidate (contrainte unique) sélectionnée pour un traitement spécial (création automatique d'index, etc.).

Je m'attends à ce que ceux qui les contestent ne voient aucune raison de traiter une clé différemment d'une autre. C'est là où je suis.

[Modifier] Apparemment, je ne peux pas commenter ma propre réponse sans 50 points.

@ Chris: Je ne pense pas qu'il y ait de mal. "Clé primaire" n'est en réalité qu'un sucre syntaxique. Je les utilise tout le temps, mais je ne pense certainement pas qu'ils sont nécessaires. Une clé unique est requise, oui, mais pas nécessairement une clé primaire.

10
Dave

Il serait très rare que la dénormalisation donne envie de disposer d’une table sans clé primaire. Les clés primaires ont automatiquement des contraintes uniques de par leur nature même en tant que PK.

Une contrainte unique serait utilisée lorsque vous souhaitez garantir l'unicité dans une colonne ADDITION à la clé primaire.

La règle de toujours avoir un PK est un bon.

http://msdn.Microsoft.com/en-us/library/ms191166.aspx

9

Vous devriez toujours avoir une clé primaire.

Cependant, je soupçonne que votre question est juste un peu trompeuse, et vous voulez en fait demander si la clé primaire doit toujours être un nombre généré automatiquement (également appelé clé de substitution), ou un champ unique qui est constitué de données significatives (également appelé données clé), comme SSN pour les personnes, ISBN pour les livres, etc.

Cette question est une guerre religieuse séculaire dans le domaine de la DB. 

À mon avis, les clés naturelles sont préférables si elles sont uniques et ne changent jamais. Cependant, vous devez faire attention, même quelque chose qui semble stable comme une personne, le SSN peut changer dans certaines circonstances.

5
JacquesB

À moins que la table ne soit une table temporaire pour la mise en scène des données pendant que vous y travaillez, vous voulez toujours mettre une clé primaire sur la table et voici pourquoi:

1 - une contrainte unique peut autoriser les valeurs NULL, mais une clé primaire never autorise les NULL. Si vous exécutez une requête avec une jointure sur des colonnes avec des valeurs null, vous éliminez ces lignes du jeu de données résultant, car null n'est pas égal à null. C’est ainsi que même les grandes entreprises peuvent commettre des erreurs comptables et doivent retraiter leurs bénéfices. Leurs requêtes ne montraient pas certaines lignes qui auraient dû être incluses dans le total car il y avait des valeurs NULL dans certaines des colonnes de leur index unique. Shoulda a utilisé une clé primaire.

2 - un index unique sera automatiquement placé sur la clé primaire, vous n’aurez donc pas à en créer un.

3 - La plupart des moteurs de base de données placent automatiquement un index clusterisé sur la clé primaire, accélérant les requêtes car les lignes sont stockées de manière contiguë dans les blocs de données. (Cela peut être modifié pour placer l'index clusterisé sur un index différent si cela accélérerait les requêtes.) Si une table ne possède pas d'index clusterisé, les lignes ne seront pas stockées de manière contiguë dans les blocs de données, rendant les requêtes plus lent car la tête de lecture/écriture doit parcourir l’ensemble du disque pour collecter les données.

4 - De nombreux environnements de développement front-end nécessitent une clé primaire pour mettre à jour la table ou effectuer des suppressions.

3
Chris OC

Les clés primaires doivent être utilisées lorsque vous établissez des relations entre cette table et d'autres tables référençant cette valeur. Toutefois, en fonction de la nature de la table et des données auxquelles vous envisagez d'appliquer la contrainte unique, vous pourrez peut-être utiliser ce champ particulier comme clé primaire naturelle plutôt que de devoir établir une clé de substitution. Bien sûr, les clés de substitution et les clés naturelles sont une toute autre discussion. :)

Des clés uniques peuvent être utilisées s'il n'y a pas de relation établie entre cette table et les autres tables. Par exemple, une table contenant une liste d'adresses e-mail valides à comparer avant d'insérer un nouvel enregistrement d'utilisateur, ou autre. Vous pouvez également utiliser des clés uniques lorsque les valeurs d'une table sont associées à une clé primaire, mais doivent également être absolument uniques. Par exemple, si vous avez une table d'utilisateurs avec un nom d'utilisateur. Vous ne voudriez pas utiliser le nom d'utilisateur en tant que clé primaire, mais il doit également être unique pour pouvoir être utilisé à des fins de connexion. 

3
Noah Goodrich

Nous devons faire ici une distinction entre les constructions logiques et les constructions physiques, et de la même manière entre la théorie et la pratique.

Pour commencer: d’un point de vue théorique, si vous n’avez pas de clé primaire, vous n’avez pas de table. C'est aussi simple que cela. Donc, votre question n'est pas de savoir si votre table devrait avoir une clé primaire (bien sûr, cela devrait être le cas), mais comment vous la marquez dans votre SGBDR.

Au niveau physique, la plupart des SGBDR implémentent la contrainte de clé primaire en tant qu'index unique. Si votre SGBDR choisi est l'un d'entre eux, il n'y a probablement pas beaucoup de différence pratique entre la désignation d'une colonne en tant que clé primaire et le simple fait d'appliquer une contrainte unique sur la colonne. Cependant: l'une de ces options rend compte de votre intention et l'autre non. Donc, la décision est une évidence.

En outre, certains SGBDR offrent des fonctionnalités supplémentaires si les clés primaires sont correctement étiquetées, telles que la création de diagrammes et la prise en charge semi-automatisée de contraintes de clé étrangère.

Quiconque vous dit d'utiliser des contraintes uniques au lieu de clés primaires devrait en général fournir une sacrée bonne raison.

2
Michael Dorfman

CLÉ PRIMAIRE

1. Null Il n'autorise pas les valeurs Null. Pour cette raison, nous nous référons à PRIMARY KEY = UNIQUE KEY + Not Null CONTRAINT. 2. INDEX Par défaut, il ajoute un index clusterisé . 3. LIMITE Une table ne peut contenir qu'une seule colonne [s] PRIMARY KEY.

CLE UNIQUE

1. Null Permet une valeur nulle. Mais une seule valeur nulle . 2. INDEX Par défaut, il ajoute un index UNIQUE non clusterisé . 3. LIMITE Une table peut avoir plusieurs colonnes de clé UNIQUE.

1
sushmita

J'ai beaucoup écrit sur ce sujet: si vous lisez quelque chose de ma part, soyez clair que je faisais probablement allusion à Jet Access spécifiquement.

Dans Jet, les tables sont physiquement ordonnées sur la clé primaire en utilisant un index en cluster non géré (est mis en cluster sur compact). Si la table n'a pas de clé PK mais que des clés candidates ont été définies à l'aide de contraintes UNIQUE sur des colonnes NOT NULL, le moteur en choisira une pour l'index cluster (si votre table n'a pas d'index cluster, elle est appelée tas, peut-être pas du tout. !) Comment le moteur sélectionne-t-il une clé candidate? Peut-il en choisir une qui inclut des colonnes nullables? Je ne sais vraiment pas. Le fait est que dans Jet, le seul moyen explicite de spécifier l'index clusterisé au moteur est d'utiliser PRIMARY KEY. Il existe bien entendu d’autres utilisations de la PK dans Jet, par exemple. il sera utilisé comme clé si une déclaration FOREIGN KEY est omise dans SQL DDL, mais encore une fois pourquoi ne pas être explicite.

Le problème avec Jet est que la plupart des personnes qui créent des tables ignorent ou ne se soucient pas des index clusterisés. En fait, la plupart des utilisateurs (je parie) placent une colonne de numérotation automatique sur chaque table et définissent la clé primaire uniquement sur cette colonne tout en omettant de définir des contraintes uniques sur les clés naturelles et candidates (si une colonne à incrémentation peut être considérée une clé sans l'exposer aux utilisateurs finaux est une autre discussion en soi). Je n'entrerai pas dans les détails sur les index clusterisés ici, mais il suffit de dire qu'une seule colonne auto-incrémentée de l'OMI est rarement un choix idéal.

Quel que soit votre moteur SQL, le choix de PRIMARY KEY est arbitraire et spécifique au moteur. Habituellement, le moteur attribue une signification particulière à la PK, vous devez donc savoir de quoi il s'agit et l’utiliser à votre avantage. J'encourage les gens à utiliser les contraintes NOT NULL UNIQUE dans l'espoir qu'ils accorderont une plus grande attention à toutes les clés candidates, en particulier lorsqu'ils ont choisi d'utiliser des colonnes de numérotation automatique qui (ne devraient pas avoir de sens dans le modèle de données). Mais je préférerais que les gens choisissent une clé bien pensée et utilisent PRIMARY KEY plutôt que de la mettre sur la colonne d’auto-incrémentation par habitude.

Est-ce que toutes les tables devraient avoir un PK? Je dis oui parce que cela signifie au moins que vous manquez à un léger avantage que le moteur offre au PK et au pire que vous n’avez aucune intégrité des données.

BTW Chris OC insiste ici sur les tables temporelles, qui nécessitent des clés primaires séquencées (minuscules) qui ne peuvent pas être implémentées via de simples contraintes PRIMARY KEY (mots clés SQL en majuscules).

1
onedaywhen

des messages disant qu'il est préférable d'utiliser une contrainte unique (index unique pour certaines bases de données) plutôt que PK

je suppose que le seul point ici est la même vieille discussion "clés naturelles vs clés de substitution", car les index uniques et pk´s sont identiques.

traduction en cours:

messages disant qu'il est préférable d'utiliser la clé naturelle plutôt que la clé de substitution

1

J'utilise habituellement à la fois PK et UNIQUE KEY. Parce que même si vous ne dénommez pas PK dans votre schéma, il en existe toujours une générée pour vous en interne. C'est vrai à la fois pour SQL Server 2005 et MySQL 5.

Mais je n'utilise pas la colonne PK dans mes SQL. Pour des raisons de gestion, telles que la suppression de lignes erronées, la recherche d’écarts entre les valeurs de PK si elle est définie sur AUTO INCREMENT. Et, il est logique d’avoir une PK sous forme de nombres et non d’ensemble de colonnes ou de tableaux de caractères.

1
yogman

le fait est qu'une clé primaire peut être une ou plusieurs colonnes identifiant de manière unique un seul enregistrement d'une table, où une contrainte unique n'est qu'une contrainte sur un champ qui n'autorise qu'une seule instance d'un élément de données donné dans une table. 

Personnellement, j'utilise GUID ou l'incrémentation automatique BIGINTS (insertion d'identité pour SQL SERVER) pour les clés uniques utilisées pour les références croisées entre mes tables. J'utiliserai ensuite d'autres données pour permettre à l'utilisateur de sélectionner des enregistrements spécifiques.

Par exemple, j'aurai une liste d'employés et un GUID associé à chaque enregistrement que j'utilise en coulisse, mais lorsque l'utilisateur sélectionne un employé, il le sélectionne en fonction des champs suivants. : Nom + Prénom + Numéro Employé. 

Ma clé principale dans ce scénario est LastName + FirstName + EmployeeNumber, tandis que la clé unique est le GUID associé.

1
Stephen Wrighton

Si vous envisagez d'utiliser LINQ-to-SQL, vos tables nécessiteront des clés primaires si vous envisagez d'effectuer des mises à jour, et une colonne timestamp si vous envisagez de travailler dans un environnement déconnecté (par exemple, passer un objet via un service WCF application).

Si vous aimez .NET, PK's et FK's sont vos amis.

0
Jarrett Meyer

Je pensais à ce problème moi-même. Si vous utilisez unique, vous allez faire mal à la 2. NF. Selon cela, chaque attribut non pk doit être dépendant de la PK. La paire d'attributs dans cette contrainte unique doit être considérée comme faisant partie de la PK.

désolé de répondre à cette question 7 ans plus tard, mais je ne voulais pas commencer une nouvelle discussion.

0
Clevemayer

Je soumets que vous pouvez avoir besoin des deux. Les clés primaires doivent par nature être uniques et non nullables. Ce sont souvent des clés de substitution car les entiers créent des jointures plus rapides que les champs de caractères et surtout que les jointures de caractères de champs multiples. Cependant, comme ils sont souvent générés automatiquement, ils ne garantissent pas l'unicité de l'enregistrement de données, à l'exclusion de l'identifiant même. Si votre table a une clé naturelle qui devrait être unique, vous devriez avoir un index unique sur elle pour empêcher la saisie de données de doublons. Ceci est une exigence de base d'intégrité des données.

Ajoutée à la remarque: c’est aussi un problème réel que les données du monde réel ne disposent souvent pas d’une clé naturelle garantissant véritablement l’unicité dans une structure de tableau normalisée, en particulier si la base de données est centrée sur les personnes. Les noms, même les nom, adresse et numéro de téléphone combinés (pensez père et fils dans le même cabinet médical) ne sont pas nécessairement uniques. 

0
HLGEM