web-dev-qa-db-fra.com

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

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

Tous ces vidages contenaient des données avec des indicateurs de chaîne au lieu de nombres entiers. Par exemple, le statut d'une publication était représenté par published, closed ou inherit plutôt que 1, 2 Ou 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 indicateurs numériques/entiers pour des données comme celle-ci. Il est évident que tinyint consomme 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?

31
trejder

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 des 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 effort de développement pour l'espace disque est également une bonne chose, du point de vue commercial.

46
Kilian Foth

Oui, le stockage de choses telles que yes ou true prendra plus d'espace qu'une minuscule. 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 (yes vs 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.

Tout d'abord, MySQL a un type enum ( 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. C'est souvent beaucoup plus utile que de stocker 1, 2 ou 3 en tant que valeur lorsque la signification est transmise 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 sous forme de clé (retour à la 1, 2 ou 3) et la valeur de published, closed et inherit sont stockées dans une autre table. En utilisant une vue ( docs ), il est alors possible de la faire ressembler à la table contenant 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.

7
user40980