Je ne connais pas très bien les bases de données et les théories sur leur fonctionnement. Est-il plus lent du point de vue des performances (insertion / mise à jour / requête) d'utiliser des chaînes pour les clés primaires que des entiers?
Je ne connais pas très bien les bases de données et les théories sur leur fonctionnement. Est-il plus lent du point de vue des performances (insertion / mise à jour / requête) d'utiliser des chaînes pour les clés primaires que des entiers?
Réponses:
Techniquement oui, mais si une chaîne a du sens pour être la clé primaire, vous devriez probablement l'utiliser. Tout dépend de la taille de la table pour laquelle vous le créez et de la longueur de la chaîne qui va être la clé primaire (des chaînes plus longues == plus difficiles à comparer). Je n'utiliserais pas nécessairement une chaîne pour une table contenant des millions de lignes, mais le ralentissement des performances que vous obtiendrez en utilisant une chaîne sur des tables plus petites sera minuscule pour les maux de tête que vous pouvez avoir en ayant un entier qui ne le fait pas ça ne veut rien dire par rapport aux données.
Un autre problème lié à l'utilisation de chaînes comme clé primaire est que, comme l'index est constamment mis en ordre séquentiel, lorsqu'une nouvelle clé est créée, elle se trouverait au milieu de l'ordre, l'index doit être reséquencé ... si vous utilisez un auto nombre entier, la nouvelle clé est simplement ajoutée à la fin de l'index.
Les insertions dans une table ayant un index clusterisé où l'insertion se produit au milieu de la séquence NE provoque PAS la réécriture de l'index. Il n'entraîne pas la réécriture des pages contenant les données. S'il y a de la place sur la page où la ligne 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, la moitié des lignes de la page allant sur une page et la moitié sur l'autre. Les pages sont ensuite reliées à la liste chaînée de pages qui comprennent des données de table qui ont l'index clusterisé. Tout au plus, vous finirez par écrire 2 pages de base de données.
Les chaînes sont plus lentes dans les jointures et dans la vraie vie, elles sont très rarement vraiment uniques (même lorsqu'elles sont censées l'être). Le seul avantage est qu'ils peuvent réduire le nombre de jointures si vous vous joignez à la table principale uniquement pour obtenir le nom. Cependant, les chaînes sont également souvent sujettes à modification, créant ainsi le problème de devoir corriger tous les enregistrements associés lorsque le nom de l'entreprise change ou que la personne se marie. Cela peut être un énorme impact sur les performances et si toutes les tables qui devraient être liées d'une manière ou d'une autre ne sont pas liées (cela se produit plus souvent que vous ne le pensez), vous pourriez également avoir des incohérences de données. Un entier qui ne changera jamais pendant toute la durée de vie de l'enregistrement est 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 est souvent d'utiliser une clé d'auto-incrémentation (ou dans certains cas spécialisés, un GUID) comme PK, puis de 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'avez pas à mettre à jour un million d'enregistrements enfants car le nom d'une société a changé.
Peu importe ce que vous utilisez comme clé primaire tant qu'elle est UNIQUE. Si vous vous souciez de la vitesse ou de la bonne conception de la base de données, utilisez int sauf si vous prévoyez de répliquer des données, puis utilisez un GUID.
S'il s'agit d'une base de données d'accès ou d'une petite application, qui s'en soucie vraiment. Je pense que la raison pour laquelle la plupart d'entre nous, les développeurs, giflons l'ancien int ou guid à l'avant, c'est parce que les projets ont une façon de grandir sur nous, et vous voulez vous laisser la possibilité de grandir.
Trop de variables. Cela dépend de la taille de la table, des index, de la nature de la chaîne clé domaine ...
En général , les entiers seront plus rapides. Mais la différence sera-t-elle assez grande pour s'en soucier? C'est difficile à dire.
Aussi, quelle est votre motivation pour choisir les cordes? Les touches numériques à incrémentation automatique sont souvent beaucoup plus faciles également. Est-ce de la sémantique? Commodité? Problèmes de réplication / déconnectés? Votre réponse ici pourrait limiter vos options. Cela rappelle également une troisième option "hybride" que vous oubliez: les Guids.
Ne vous inquiétez pas des performances tant que vous n’avez pas obtenu une conception simple et solide qui correspond au sujet décrit par les données et s’adapte bien à l’utilisation prévue des données. Ensuite, si des problèmes de performances apparaissent, vous pouvez les résoudre en peaufinant le système.
Dans ce cas, il est presque toujours préférable d'utiliser une chaîne comme clé primaire naturelle, à condition que vous puissiez y faire confiance. Ne vous inquiétez pas s'il s'agit d'une chaîne, tant que la chaîne est raisonnablement courte, disons environ 25 caractères maximum. Vous ne paierez pas un gros prix en termes de performances.
Les personnes de saisie de données ou les sources de données automatiques fournissent-elles toujours une valeur pour la clé naturelle supposée ou sont parfois omises? Est-ce parfois erroné 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 un substitut. Si vous inventez un substitut, vous pouvez aussi inventer un entier. Ensuite, vous devez vous soucier de savoir où cacher le substitut à la communauté des utilisateurs. Certains développeurs qui n'ont pas caché la clé de substitution en sont venus à le regretter.
Les indices impliquent de nombreuses comparaisons.
En règle générale, les chaînes sont plus longues que les entiers et des règles de classement peuvent être appliquées pour la comparaison, de sorte que la comparaison de chaînes est généralement une tâche plus intensive en calcul que la comparaison d'entiers.
Parfois, cependant, il est plus rapide d'utiliser une chaîne comme clé primaire que de créer une jointure supplémentaire avec une string to numerical id
table.
Oui, mais à moins que vous ne vous attendiez à avoir des millions de lignes, ne pas utiliser de clé basée sur une chaîne car elle est plus lente est généralement une «optimisation prématurée». Après tout, les chaînes sont stockées sous forme de grands nombres tandis que les touches numériques sont généralement stockées sous forme de nombres plus petits.
Une chose à surveiller, cependant, est si vous avez des index clusterisés sur une clé any et que vous 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.
Deux raisons d'utiliser des entiers pour les colonnes PK:
Nous pouvons définir l'identité du champ entier qui s'est incrémenté automatiquement.
Lorsque nous créons des PK, la base de données crée un index (Cluster ou Non Cluster) qui trie les données avant qu'elles ne soient stockées dans la table. En utilisant une identité sur un PK, l'optimiseur n'a pas besoin de vérifier l'ordre de tri avant d'enregistrer un enregistrement. Cela améliore les performances sur les grandes tables.
Quelle est votre raison d'avoir une chaîne comme clé primaire?
Je voudrais simplement définir la clé primaire sur un champ entier à incrémentation automatique et mettre un index sur le champ de chaîne.
De cette façon, si vous effectuez des recherches sur la table, elles devraient être relativement rapides, et toutes vos jointures et recherches normales ne seront pas affectées par leur vitesse.
Vous pouvez également contrôler la quantité de champ de chaîne qui est indexée. En d'autres termes, vous pouvez dire "indexer uniquement les 5 premiers caractères" si vous pensez que cela suffira. Ou si vos données peuvent être relativement similaires, vous pouvez indexer tout le champ.
Du point de vue des performances - La chaîne Oui (PK) ralentira les performances par rapport aux performances obtenues à l'aide d'un entier (PK), où PK ---> Clé primaire.
Du point de vue des exigences - Bien que cela ne fasse pas partie de votre question, je voudrais encore le mentionner. Lorsque nous traitons d'énormes données sur différentes tables, nous recherchons généralement l'ensemble probable de clés pouvant être définies pour une table particulière. Ceci est principalement dû au fait qu'il existe de nombreuses tables et que la plupart du temps, chacune ou une table serait liée à l'autre par le biais d'une relation (un concept de clé étrangère). Par conséquent, nous ne pouvons vraiment pas toujours choisir un entier comme clé primaire, nous optons plutôt pour une combinaison de 3, 4 ou 5 attributs comme clé primaire pour ces tables. Et ces clés peuvent être utilisées comme clé étrangère lorsque nous relions les enregistrements à une autre table. Cela rend utile de relier les enregistrements entre différentes tables lorsque cela est nécessaire.
Par conséquent, 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 nécessaire.
Il pourrait y avoir un très gros malentendu lié à la chaîne dans la base de données. Presque tout le monde pense que la représentation des nombres dans les bases de données est plus compacte que celle des 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 Une chaîne comme représentation que de l'autre.
La vitesse d'utilisation du nombre ou de la chaîne dépend davantage de l'indexation que du type lui-même.
Par défaut, ASPNetUserIds contient 128 chaînes de caractères et les performances sont très bien.
Si la clé DOIT être unique dans la table, elle doit être la clé. Voici pourquoi;
clé de chaîne primaire = Corriger les relations de base de données, 1 clé de chaîne (la principale) et 1 chaîne d'index (la principale).
L'autre option est une clé int typique, mais si la chaîne DOIT être unique, vous devrez probablement ajouter un index en raison de requêtes non-stop pour valider ou vérifier qu'il est 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 un index de chaîne unique et le fait de devoir valider manuellement la même chaîne n'existe pas (quelque chose comme une vérification SQL 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, cela devrait être une situation 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 jusqu'à ce que vous en ayez besoin .