web-dev-qa-db-fra.com

Chaînes en tant que clés primaires dans la base de données SQL

Je ne connais pas très bien les bases de données et leurs théories. Est-il plus lent, du point de vue des performances (insertion/mise à jour/interrogation), d’utiliser des chaînes pour les clés primaires que des nombres entiers? 

145
mainstringargs

Techniquement oui, mais si une chaîne a du sens d'être la clé primaire, vous devriez probablement l'utiliser. Tout dépend de la taille de la table que vous créez et de la longueur de la chaîne qui sera la clé primaire (des chaînes plus longues == plus difficiles à comparer). Je n'utiliserais pas nécessairement une chaîne pour une table comportant des millions de lignes, mais le ralentissement des performances que vous obtiendrez en utilisant une chaîne sur des tables plus petites sera minime pour les maux de tête que vous pouvez avoir en ayant un entier qui ne ne veut rien dire par rapport aux données.

154
kemiller2002

Un autre problème lié à l'utilisation de Strings en tant que clé primaire est que, comme l'index est constamment placé dans un ordre séquentiel, lors de la création d'une nouvelle clé située au milieu de cet ordre, l'index doit être reséquencé nombre entier, la nouvelle clé vient d’être ajoutée à la fin de l’index.

59
Jeff Martin

Les insertions dans une table ayant un index clusterisé où l'insertion a lieu au milieu de la séquence NE provoque PAS la réécriture de l'index. Cela ne provoque pas une réécriture des pages contenant les données. S'il y a de la place sur la page où la rangée ira, elle est placée dans cette page. La page unique sera reformatée pour placer la ligne au bon endroit dans la page. Lorsque la page est pleine, une division de page se produit, avec la moitié des lignes de la page allant d’une page à l’autre. Les pages sont ensuite reliées dans la liste liée des pages qui comprennent des données de table contenant l'index clusterisé. Tout au plus, vous finirez par écrire 2 pages de base de données. 

17
Mark Thompson

Les chaînes sont plus lentes dans les jointures et dans la vie réelle, elles sont très rarement vraiment uniques (même lorsqu'elles sont supposées l'être). Le seul avantage est qu'ils peuvent réduire le nombre de jointures si vous rejoignez la table primaire uniquement pour obtenir le nom. Toutefois, les chaînes sont également souvent sujettes à modification, ce qui pose le problème de devoir corriger tous les enregistrements associés lorsque le nom de la société change ou que la personne se marie. Cela peut être un énorme problème de performances et si toutes les tables qui devraient être liées d’une manière ou d’une autre ne le sont pas (cela se produit plus souvent que vous ne le pensez), vous risquez également d’avoir des incohérences dans les données. Un nombre entier qui ne changera jamais au cours de la vie de l'enregistrement constitue un choix beaucoup plus sûr du point de vue de l'intégrité des données ainsi que du point de vue des performances. Les clés naturelles ne sont généralement pas si bonnes pour la maintenance des données.

Je tiens également à souligner que le meilleur des deux mondes consiste souvent à utiliser une clé auto-incrémentante (ou dans certains cas spécialisés, un GUID) en tant que clé PK, puis à mettre un index unique sur la clé naturelle. Vous obtenez les jointures les plus rapides, vous n’obtenez pas d’enregistrements en double et vous n’aurez pas à mettre à jour un million d’enregistrements enfants car un nom de société a changé. 

11
HLGEM

Peu importe ce que vous utilisez comme clé primaire, à condition que ce soit UNIQUE. Si vous vous souciez de la rapidité ou de la bonne conception de la base de données, utilisez int, sauf si vous envisagez de répliquer des données, utilisez un GUID.

S'il s'agit d'une base de données d'accès ou d'une application minuscule, alors qui s'en soucie vraiment. Je pense que la raison pour laquelle la plupart d’entre nous développeurs giflons l’ancien int ou guid au début, c’est parce que les projets ont le potentiel de prendre de l’ampleur et que vous voulez vous laisser la possibilité de le faire. 

7
Al Katawazi

Ne vous inquiétez pas pour les performances tant que vous n’avez pas une conception simple et solide qui concorde avec le sujet décrit par les données et qui correspond bien à l’utilisation prévue de ces données. Ensuite, si des problèmes de performances surviennent, vous pouvez les résoudre en modifiant le système.

Dans ce cas, il est presque toujours préférable d'utiliser une chaîne comme clé primaire naturelle, à condition de pouvoir y faire confiance. Ne vous inquiétez pas si c'est une chaîne, tant qu'elle est raisonnablement courte, disons environ 25 caractères maximum. Vous ne paierez pas un lourd tribut en termes de performances.

Les personnes chargées de la saisie des données ou les sources de données automatiques fournissent-elles toujours une valeur pour la clé naturelle supposée ou sont-elles parfois omises? Est-il parfois faux dans les données d'entrée? Si oui, comment les erreurs sont-elles détectées et corrigées? 

Les programmeurs et les utilisateurs interactifs qui spécifient des requêtes peuvent-ils utiliser la clé naturelle pour obtenir ce qu'ils veulent? 

Si vous ne pouvez pas faire confiance à la clé naturelle, inventez une mère porteuse. Si vous inventez un substitut, vous pourriez aussi bien inventer un entier. Ensuite, vous devez vous demander s’il faut cacher le substitut à la communauté des utilisateurs. Certains développeurs qui n'ont pas dissimulé la clé de substitution en sont venus à le regretter.

4
Walter Mitty

Trop de variables. Cela dépend de la taille de la table, des index, de la nature du domaine clé de chaîne ...

Généralement, les entiers seront plus rapides. Mais la différence sera-t-elle assez grande pour qu'on s'en occupe? C'est difficile à dire.

Aussi, quelle est votre motivation pour choisir des chaînes? Les clés numériques à incrémentation automatique sont souvent aussi plus faciles Est-ce la sémantique? Commodité? Problèmes de réplication/déconnectés? Votre réponse ici pourrait limiter vos options. Cela évoque également une troisième option «hybride» que vous oubliez: les guides. 

4
Joel Coehoorn

Les indices impliquent beaucoup de comparaisons.

En règle générale, les chaînes sont plus longues que les nombres entiers et les règles de classement peuvent être appliquées à la comparaison. La comparaison de chaînes est donc généralement une tâche beaucoup plus laborieuse que la comparaison de nombres entiers. 

Cependant, il est parfois plus rapide d’utiliser une chaîne comme clé primaire que de créer une jointure supplémentaire avec une table string to numerical id.

2
Quassnoi

Oui, mais sauf si vous vous attendez à avoir des millions de lignes, n'utilisez pas de clé basée sur des chaînes, car elle est généralement plus lente. Après tout, les chaînes sont stockées sous forme de gros chiffres alors que les clés numériques sont généralement stockées sous forme de nombres plus petits.

Une chose à surveiller, cependant, est si vous avez des index en cluster sur une clé quelconque et effectuez un grand nombre d'insertions non séquentielles dans l'index. Chaque ligne écrite entraînera la réécriture de l'index. si vous effectuez des insertions par lots, cela peut vraiment ralentir le processus.

2
Yes - that Jake.

Deux raisons d'utiliser des entiers pour les colonnes PK:

  1. Nous pouvons définir l'identité du champ entier incrémenté automatiquement.

  2. Lorsque nous créons des PK, la base de données crée un index (en cluster ou non en cluster) qui trie les données avant leur stockage dans la table. En utilisant une identité sur une PC, l'optimiseur n'a pas besoin de vérifier l'ordre de tri avant de sauvegarder un enregistrement. Cela améliore les performances sur les grandes tables.

2
Jatinder Singh

Du point de vue des performances - Yes string (PK) ralentira les performances par rapport aux performances obtenues avec un entier (PK), où PK ---> Primary Key.

Du point de vue des exigences - Bien que cela ne fasse pas partie de votre question, je voudrais néanmoins mentionner. Lorsque nous traitons d’énormes données dans différentes tables, nous recherchons généralement l’ensemble probable de clés pouvant être définies pour une table donnée. Cela est principalement dû au fait qu'il existe de nombreuses tables et que la plupart des tables sont liées les unes aux autres par une relation (un concept de clé étrangère). Par conséquent, nous ne pouvons vraiment pas toujours choisir un entier en tant que clé primaire, mais plutôt une combinaison de 3, 4 ou 5 attributs en tant que clé primaire pour ces tables. Et ces clés peuvent être utilisées comme clé étrangère lorsque nous associons les enregistrements à une autre table. Cela rend utile de relier les enregistrements de différentes tables lorsque cela est nécessaire.

Donc pour une utilisation optimale - Nous faisons toujours une combinaison de 1 ou 2 entiers avec 1 ou 2 attributs de chaîne, mais encore une fois seulement si cela est requis.

1
Arijit

Quelle est votre raison d'avoir une chaîne comme clé primaire?

Je voudrais juste définir la clé primaire sur un champ entier incrémenté automatiquement et mettre un index sur le champ chaîne.

Ainsi, si vous effectuez des recherches sur la table, elles devraient être relativement rapides, et toutes vos jointures et vos recherches normales ne seront pas affectées par leur vitesse.

Vous pouvez également contrôler la quantité du champ de chaîne à indexer. En d'autres termes, vous pouvez dire "n'indexez que les 5 premiers caractères" si vous pensez que cela suffira. Ou si vos données peuvent être relativement similaires, vous pouvez indexer le champ entier.

1
John Bubriski

Il pourrait y avoir un très gros malentendu lié à la chaîne dans la base de données. Presque tout le monde a pensé que la représentation des nombres dans la base de données est plus compacte que pour les chaînes. Ils pensent que dans db-s, les nombres sont représentés comme dans la mémoire. Mais ce n'est pas vrai. Dans la plupart des cas, la représentation numérique est plus proche de A chaîne, comme la représentation. 

La vitesse d'utilisation du nombre ou de la chaîne dépend davantage de l'indexation que du type lui-même.

0
takacsot

Par défaut, ASPNetUserIds comporte 128 chaînes de caractères et les performances sont optimales.

Si la clé DOIT être unique dans la table, il doit s'agir de la clé. Voici pourquoi; 

clé de chaîne principale = relations de base de données correctes, 1 clé de chaîne (primaire) et 1 chaîne d'index (primaire).  

L'autre option est une clé int typique, mais si la chaîne A unique, vous devrez probablement ajouter un index en raison de requêtes non-stop pour valider ou vérifier son caractère unique.

Donc, en utilisant une clé d’identité int = relations de base de données incorrectes, 1 clé int (primaire), 1 index int (primaire), probablement une chaîne unique Index, et devant valider manuellement la même chaîne n’existant pas vérifier peut-être).

Pour obtenir de meilleures performances en utilisant un int sur une chaîne pour la clé primaire, lorsque la chaîne DOIT être unique, la situation doit être très étrange. J'ai toujours préféré utiliser des clés de chaîne. Et en règle générale, ne dénormalisez pas une base de données tant que vous n'avez pas NEED to.

0
JPoole