Pourquoi stocker des drapeaux / énumérations dans une base de données sous forme de chaînes au lieu d'entiers?

29

J'ai parcouru les vidages SQL de certains CMS célèbres, y compris Drupal 7, Wordpress (une version assez ancienne) et des applications personnalisées basées sur Python.

Tous ces vidages contenaient des données avec des indicateurs de chaîne au lieu de nombres entiers. Par exemple, un statut de poste était représenté comme published, closedou inheritplutôt que 1, 2ou 3.

J'ai une expérience assez limitée dans la conception de bases de données et je n'ai jamais dépassé les simples SQL, mais on m'a toujours enseigné que je devrais utiliser des drapeaux numériques / entiers pour des données comme celle-ci. Il est évident que tinyintconsomme beaucoup moins d'espace dans une base de données que, par exemple varchar(9),.

Alors qu'est-ce qui me manque? N'est-ce pas un gaspillage de stockage de données et une redondance de données? La navigation, la recherche et l'indexation ne seraient-elles pas un peu plus rapides si ces colonnes utilisaient des entiers au lieu de chaînes?

trejder
la source
7
Êtes-vous sûr qu'ils n'utilisent pas réellement dev.mysql.com/doc/refman/5.0/en/enum.html qui ressemblera à une chaîne dans le vidage. Quoi qu'il en soit, je pense que de nos jours, cela compte presque comme une micro-optimisation.
Esben Skov Pedersen,
2
Cette question est fondamentalement un appel à l'autorité.
DeadMG
3
Pas une réponse complète, mais ... vous connaissez le langage de script Lua? Réputé pour être direct et performant, utilisé pour écrire des moteurs de jeu entiers, etc.? Étonnamment, ils n'ont jamais pris la peine d'avoir un type de numéro. Leur code de gestion des chaînes est si efficace qu'ils peuvent additionner des nombres qui sont en fait des chaînes, dans le code du moteur de jeu sensible au temps. Comme JavaScript, ils n'ont même pas d'objets - juste des tables de hachage très sophistiquées. Le point de vue du programmeur C sur "une vaste gamme de chars? Quelle inefficacité!" est dépassé par rapport à 2015.
Katana314
2
Modifié pour supprimer la partie "appel à l'autorité" et rouvert-voté, car la question sur l'utilisation des chaînes plutôt que des entiers est parfaitement d'actualité tant qu'il ne s'agit pas spécifiquement de ces "autorités".
Ixrec

Réponses:

45

Oui, le stockage de chaînes au lieu de nombres peut utiliser plus d'espace. La raison pour laquelle les plates-formes de haut niveau le font de toute façon est qu'elles pensent que les avantages de cette solution sont supérieurs au coût.

Quels sont les bénéfices? Vous pouvez facilement lire un vidage de base de données et comprendre de quoi il s'agit sans mémoriser les tables d'énumération, et même les interfaces graphiques semi-officielles peuvent simplement utiliser les valeurs par thèmes plutôt que de transformer l'enregistrement qu'elles obtiennent. (Il s'agit d'une forme de base de compromis espace disque / temps de traitement.)

Et le coût? La capacité de stockage de données n'a pas été le goulot d'étranglement dans le CMS depuis longtemps, car les disques sont devenus si gros et si bon marché. Le temps du programmeur, en revanche, devient généralement plus cher - donc tout ce qui échange des efforts de développement contre de l'espace disque est également une bonne chose, du point de vue commercial.

Kilian Foth
la source
7

Oui, le stockage d'objets tels que yesou trueprendra plus de place qu'une petite pièce. Cela ne devrait pas être surprenant. Il rend également l'indexation et donc les jointures moins efficaces pour la base de données. Il a également pour inconvénient une confusion possible quant à la valeur correcte ( yesvs y).

Cependant, il existe de nombreuses approches qui ressemblent au stockage de chaînes dans la base de données (en particulier MySQL) qui sont efficaces.

Premièrement, MySQL a un enumtype ( docs ) qui peut ressembler à un ensemble de chaînes booléen ou restreint lorsqu'il est configuré de cette façon. Il applique également que seules des valeurs valides sont entrées. Ceci est souvent beaucoup plus utile que le stockage 1, 2ou en 3tant que valeur car le sens est transmis avec les informations. L'énumération est accompagnée de la pénalité selon laquelle un changement de schéma est nécessaire pour ajouter ou supprimer des types.

Cela nous amène à une table enfant et des clés étrangères (applicables à toutes les bases de données). Oui, vous stockez une valeur en tant que clé (retour au 1, 2ou 3) et la valeur published, closedet inheritsont stockés dans une autre table. En utilisant une vue ( docs ), il est alors possible de donner l'impression que la table contient la chaîne plutôt que la clé. Cela présente l'avantage qu'aucune modification de schéma n'est requise pour ajouter ou supprimer des entrées de la table enfant.

Exactement comment les choses sont stockées, il faudrait regarder la DDL réelle du schéma pour déterminer quelle méthode est utilisée et obtenir un indice des compromis qu'ils ont sélectionnés.


la source