396 votes

Le stockage d'une liste délimitée dans une colonne de base de données est-il vraiment si mauvais?

Imaginez un formulaire web avec un ensemble de cases à cocher (tout ou peuvent être sélectionnés). J'ai choisi de les enregistrer dans une liste séparée par des virgules de valeurs stockées dans une colonne de la table de base de données.

Maintenant, je sais que la bonne solution serait de créer un deuxième tableau et correctement normaliser la base de données. Il était plus rapide à mettre en œuvre la solution de facilité, et je voulais avoir une preuve de concept de cette application rapidement et sans avoir à passer trop de temps sur elle.

Je pensais que le gain de temps et une simplification de code en valait la peine, dans ma situation, c'cette défendable choix de conception, ou devrais-je avoir normalisé depuis le début?

Peu plus de contexte, c'est une petite application qui remplace essentiellement un fichier Excel qui a été stocké sur un dossier partagé. Je me demande aussi parce que je suis en train de réfléchir au nettoyage de la programm et le rendre plus facile à gérer. Il y a des choses là je ne suis pas entièrement satisfait, l'un d'eux est le sujet de cette question.

617voto

Bill Karwin Points 204877

En outre, l'atteinte de la Première Forme Normale en raison de la répétition d'un groupe de valeurs stockées dans une seule colonne, séparées par des virgules pour les listes de beaucoup d'autres plus de problèmes pratiques:

  • Ne peux pas garantir que chaque valeur est le bon type de données: aucun moyen de l'empêcher 1,2,3,de la banane,5
  • Ne pouvez pas utiliser les contraintes de clé étrangère pour lier les valeurs à un tableau de recherche; aucun moyen d'appliquer l'intégrité référentielle.
  • Ne peut pas appliquer l'unicité: aucun moyen de prévenir la 1,2,3,3,3,5
  • Ne pouvez pas supprimer une valeur dans la liste sans avoir à aller chercher de l'ensemble de la liste.
  • Ne peut pas stocker une liste de plus que ce qui convient dans la colonne de chaîne.
  • Dur à la recherche de toutes les entités ayant une valeur dans la liste, vous devez utiliser de l'inefficacité d'un tableau de numérisation.
  • Dur de compter les éléments dans la liste, ou faire d'autres des requêtes d'agrégation.
  • Difficile de rejoindre les valeurs de la table de recherche.
  • Dur pour récupérer la liste dans l'ordre de tri.
  • Le stockage des entiers comme des chaînes de caractères prend environ deux fois plus d'espace que le stockage binaire des entiers. Sans parler de la place prise par les virgules.

Pour résoudre ces problèmes, vous avez à écrire des tonnes de code de l'application, de réinventer les fonctionnalités que le SGBD fournit déjà beaucoup plus efficacement.

Séparées par des virgules, les listes sont assez mal que j'ai fait ce le premier chapitre de mon livre: SQL Antipatterns: Éviter les Pièges de la Programmation de Base de données.

Il ya des moments où vous avez besoin d'employer la dénormalisation, mais comme @OMG Poneys mentionne, ce sont les cas d'exception. Tout non-relationnelle "optimisation" des avantages d'un type de requête, au détriment d'autres utilisations des données, assurez-vous donc de savoir qui de vos requêtes doivent être traités de manière spécialement qu'ils méritent de la dénormalisation.

48voto

Hammerite Points 10786

"Une des raisons était de la paresse".

Cela sonne des cloches d'alarme. La seule raison pour laquelle vous devriez faire quelque chose comme cela, c'est que vous savez comment le faire "le bien" mais vous êtes venus à la conclusion qu'il est tangible raison de ne pas le faire de cette façon.

Ceci dit: si les données que vous choisissez de stocker cette façon est de données que vous n'aurez jamais besoin de la requête, alors il y a peut être un étui pour le ranger dans la voie que vous avez choisie.

(Certains utilisateurs ne conteste l'énoncé dans mon précédent paragraphe, en disant que "vous ne pouvez jamais savoir que les exigences qui seront ajoutées dans le futur". Ces utilisateurs sont soit erronées ou indiquant une conviction religieuse. Il est parfois avantageux de travail aux besoins que vous avez devant vous.)

42voto

OMG Ponies Points 144785

Il y a de nombreuses questions sur DONC de demander:

  • comment obtenir un nombre de valeurs spécifiques à partir de la liste séparée par des virgules
  • comment obtenir les enregistrements qui n'ont que la même 2/3/etc spécifique de la valeur à partir de cette liste séparée par des virgules

Un autre problème avec la liste séparée par des virgules est de s'assurer que les valeurs sont cohérentes - stocker du texte signifie la possibilité de fautes de frappe...

Ce sont tous des symptômes de dénormalisée de données, et de mettre en évidence pourquoi vous devriez toujours le modèle de données normalisées. La dénormalisation peut être une optimisation de la requête, pour être appliquée lorsque le besoin s'en fait lui-même présente.

19voto

bobbymcr Points 14916

En général, tout peut être défendable s'il répond aux exigences de votre projet. Cela ne signifie pas que les gens seront d'accord avec ou veulent défendre votre décision ...

En général, stocker des données de cette manière est sous-optimal (par exemple, plus difficile à faire des requêtes efficaces) et peut entraîner des problèmes de maintenance si vous modifiez les éléments de votre formulaire. Peut-être auriez-vous pu trouver un terrain d'entente et utiliser un entier représentant un ensemble de drapeaux binaires à la place?

10voto

duffymo Points 188155

Oui, je dirais que c'est vraiment mauvais. C'est un choix défendable, mais ce n'en est pas correcte ou bonne.

Il rompt la première forme normale.

Une seconde critique est que de mettre les entrées brutes directement les résultats dans une base de données, sans aucune validation ou de liaison à tous, vous laisse ouvert aux attaques par injection SQL.

Ce que vous appelez la paresse et le manque de connaissances SQL est la substance que les néophytes. Je vous recommande de prendre le temps de le faire correctement et de le voir comme une occasion d'apprendre.

Ou le laisser tel qu'il est et apprendre la leçon douloureuse d'une attaque par injection SQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X