Cela me dérange depuis un moment. La plupart du temps, lorsqu'il s'agit de stocker des données dans des structures telles que des tables de hachage, des programmeurs, des livres et des articles insistent sur le fait que l'indexation des éléments dans ces structures par des valeurs de chaîne est considérée comme une mauvaise pratique. Pourtant, jusqu'à présent, je n'ai pas trouvé une seule source de ce type pour expliquer également POURQUOI elle est considérée comme une mauvaise pratique. Cela dépend-il du langage de programmation? Sur le cadre sous-jacent? Sur la mise en œuvre?
Prenez deux exemples simples, si cela vous aide:
Une table de type SQL où les lignes sont indexées par une clé primaire String.
Un dictionnaire .NET où les clés sont des chaînes.
username
, la clé primaire d'uneusers
table n'est probablement pas la meilleure idée, et vous préféreriez un identifiant d'incrémentation automatique. Mais c'estusername
une chaîne n'est qu'accessoire, être une propriété mutable est le principal problèmeRéponses:
Tout cela a à voir avec les deux choses essentiellement:
1) La vitesse de recherche (où les entiers, par exemple, se portent beaucoup mieux)
2) La taille des index (où les index de chaîne exploseraient)
Maintenant, tout dépend de vos besoins et de la taille de l'ensemble de données. Si une table ou une collection contient 10 à 20 éléments, le type de clé n'est pas pertinent. Ce sera très rapide même avec une clé de chaîne.
PS Peut ne pas être lié à votre question, mais les guides sont également considérés comme mauvais pour les clés de base de données (Guid de 16 octets contre un entier de 4 octets). Sur les gros volumes de données, les GUID ralentissent la recherche.
la source
Il y a un autre problème avec l'utilisation de chaînes comme clés, ou plus précisément, l'utilisation de littéraux de chaîne comme clés, en mettant de côté des raisons de performances / efficacité pures. Typos. Si vous utilisez des littéraux de chaîne comme clés dans un dictionnaire, vous vous préparez à une mauvaise surprise quand on
"ReceiverId"
devient un"RecieverId"
. Configurez des constantes pour stocker les valeurs clés et réutilisez-les chaque fois que vous accédez au dictionnaire.Trivial et évident, vous pouvez dire, mais un nombre étonnant d'exemples de code .NET sur le Web utilise des littéraux de chaîne, propageant cette pratique douteuse. ASP.NET avec toutes les sessions, ViewStates et QueryParams disséminés à travers la base de code est particulièrement coupable ici.
la source
"1"
et"1 "
dans la même table.Il y a de nombreux compromis ici. En fait, j'utilise fréquemment des clés de chaîne, mais j'inclus souvent des clés secondaires de substitution pour les jointures (ce serait évidemment l'inverse si j'utilisais MySQL). Il y a des cas où je n'en ai pas cependant.
Tout d'abord, je suis un fan de déclarer les clés naturelles comme la clé primaire où la base de données peut bien gérer cela (PostgreSQL par exemple). Cela aide à la normalisation et permet une conception plus claire de la base de données. Les touches de substitution facilitent la connexion.
Il y a deux raisons pour lesquelles j'ajoute généralement des clés de substitution:
On ne sait pas toujours ce qu'est une clé naturelle. Parfois, ceux-ci doivent être modifiés. Changer une clé composite naturelle lorsqu'elle est utilisée pour les jointures et l'intégrité référentielle est compliqué et sujet aux erreurs.
Les performances de jointure sur les clés composites sont problématiques et une fois que vous suivez la route des clés naturelles, vous y êtes coincé.
Dans les cas où une clé naturelle est une définition, une seule colonne et du texte, cependant, je joins généralement la clé de chaîne. Ma raison est que cela évite souvent les jointures lors de la recherche. L'utilisation la plus courante consiste à fournir une conception de base de données appropriée autour du cas d'utilisation des types d'énumération. Dans la plupart des cas, ceux-ci ne nécessitent pas la jointure supplémentaire pour les requêtes de routine. Donc, lorsque c'est le cas, les clés de chaîne en tant que clés de jointure ont un sens parfait.
Par exemple, dans LedgerSMB, nous stockons les catégorisations de compte. Celles-ci sont identifiées par une référence de chaîne et d'autres données sont stockées avec la référence de chaîne qui est utilisée pour appliquer les règles concernant les combinaisons de catégorisations qui peuvent affecter un compte. La seule fois où la logique est nécessaire est lors de l'enregistrement d'un ensemble de catégorisations, nous nous joignons donc à la clé de chaîne.
Quant à savoir pourquoi la valeur par défaut serait des clés entières, je ne pense pas que ce soit juste une question de taille d'index. Un gros problème est la gestion des clés. Étant donné que la clé est arbitraire et que vous pouvez avoir affaire à des millions d'enregistrements, vous devez avoir un moyen de générer des chaînes uniques. Il y a des cas où les gens utilisent des UUID pour cela, mais il y a une chance non nulle de collision UUID, et où des milliards d'enregistrements sont stockés, cette chance devient suffisamment élevée que l'on pourrait réellement voir tandis que la probabilité de collision avec des types entiers incrémentés est nulle par définition.
la source
Il existe un certain nombre de problèmes potentiels liés à l'utilisation de chaînes comme clés, en particulier lorsqu'il s'agit de tables de type SQL. Comme mentionné par @bunny, les index de vos tables vont être plus grands, mais je pense que plus important encore, toute relation de clé étrangère avec la table impliquera que les deux tables contiennent la chaîne par opposition à un identificateur plus léger (entier) . Si vous trouvez qu'il y a encore plus de tables avec des références à la première, les clés de chaîne se multiplieront dans votre base de données.
la source
Ce n'est pas une mauvaise idée en soi, c'est généralement avec un recul de 20/20 un mauvais compromis de conception. La flexibilité et la gamme de cordes par rapport au coût et à la complexité supplémentaires.
Si l'entier fait la plage de travaux et que la majeure partie du traitement coûteux n'a pas besoin de savoir ce que l'entier représente, utilisez-en un.
la source
Vous avez en quelque sorte récupéré les mauvaises données d'une table de hachage.
Voulez-vous dire "DaytimeTelephone" ou "EveningTelephone"?
ou
Voulez-vous dire 1234567 ou 1234576?
Alors que les chiffres sont sans doute plus efficaces pour la machine , chaque fois que les choses tournent mal (et ils le font), il revient à vous et à moi de comprendre ce qui s'est passé et, à ce stade, d'économiser quelques octets de stockage et quelques micro (nano?) - les secondes de traitement perdent en clarté à chaque fois.
la source
Beaucoup de compromis et pas de bonne réponse. De nombreux programmeurs n'envisageraient jamais d'utiliser des clés de chaîne dans la base de données car ils ne connaissent pas le hachage et le fonctionnement d'une base de données. Les clés de chaîne tant qu'elles sont extrêmement stables ou sans signification (substituts) sont un bon choix de conception dans de nombreuses circonstances.
la source
la clé de chaîne aura un sens, lorsqu'il s'agit d'une table de recherche avec environ 10 à 100 enregistrements de chaîne courts; les données associées sont plus lisibles + par exemple, le suivi des modifications (identifiant numérique / guid vs chaîne par exemple "Administrateur"); btw, la base de données des membres ASP.NET utilise des clés de chaîne pour AspNetRoles.
la source