J'ai une discussion intéressante avec un autre concepteur de base de données sur la normalisation. Dans cet exemple, nous avons une table GameTitles et chaque enregistrement doit contenir l'année de sortie du jeu. Il dit que 2NF exige que tout soit normalisé, donc, pour être conforme, le champ année doit être divisé en une table ReleaseYears avec sa propre clé primaire référencée par la table GameTitles. Je dis que cela devrait rester comme un champ sur la table GameTitles elle-même.
Mon argument pour cela est qu'une année n'est qu'une valeur numérique non primitive qui est statique par sa nature même (c'est-à-dire que 2011 sera toujours 2011). De ce fait, il sert de son propre identifiant et n'a besoin de rien pour le référencer puisqu'il est ce qu'il est. Cela introduit également une maintenance supplémentaire puisque vous devez maintenant ajouter une nouvelle année au tableau juste pour la référencer. Si vous préremplissez le tableau avec un large éventail d'années, vous disposez alors d'enregistrements supplémentaires qui n'auront potentiellement aucune référence à eux. Cela augmente également la taille de la base de données, car vous disposez désormais d'une table supplémentaire, d'un surcoût d'enregistrement et de la clé primaire supplémentaire pour l'année elle-même. Si vous conservez l'année comme champ sur la table GameTitles, vous éliminez tous ces frais de maintenance et frais généraux supplémentaires.
Réflexions là-dessus?
edit: destiné à publier ceci sur StackOverflow. Quelqu'un peut-il voter pour le supprimer ou le signaler à l'attention?
la source
Réponses:
L'autre concepteur de base de données a tout simplement tort, mais votre raisonnement est également faux. Supposons que vous commenciez par cette table, qui a une seule clé candidate, "game_title".
Vous évaluez si c'est dans 2NF en vous posant ces questions.
Q: Tout d'abord, est-ce en 1NF?
R: Oui, ça l'est.
Q: Quels sont les principaux attributs (attributs qui font partie d'une clé candidate)?
R: "game_title" est le seul attribut principal.
Q: Quels sont les attributs non premiers?
R: "year_first_released" est le seul.
Q: "year_first_released" est-il fonctionnellement dépendant de l'ensemble de "game_title", ou d'une partie seulement de celui-ci?
R: La seule clé candidate, "game_title", est une seule colonne; il n'a même pas de pièces. Donc "year_first_released" est fonctionnellement dépendant de l'ensemble de "game_title".
Voilà. Vous avez trouvé 2NF.
Vous pouvez couper certains des termes formels en demandant d'abord si c'est en 1NF, puis en répondant à cette question.
Q: Existe-t-il des clés candidates composites?
R: Non.
Voilà. Vous avez retrouvé 2NF.
Par définition, pour qu'une table viole 2NF, elle doit avoir au moins une clé candidate qui a plus d'une colonne.
Voici vos raisons de rejeter l'opinion de votre ami.
Aucune de ces raisons n'a quoi que ce soit à voir avec le fait qu'une table soit en 2NF.
Lors de la conception d'une base de données, il n'est pas faux de prendre en compte les problèmes de maintenance, la taille de la base de données, les lignes non référencées, les contraintes de plage, etc. C'est juste faux d'appeler ces choses normalisation.
Oh, et ce tableau à deux colonnes que j'ai fourni ci-dessus - il est en 5NF.
la source
La création d'une table distincte pour n'importe quel attribut n'a rien à voir avec la normalisation. 2NF, 3NF, BCNF, 4NF, 5NF sont tous concernés par l'élimination des dépendances non clés. Si vous supprimez un attribut unique dans une nouvelle table et le remplacez par un attribut de clé étrangère, les dépendances dans la table seront logiquement les mêmes qu'avant - de sorte que la version révisée de la table n'est ni plus ni moins normalisée qu'elle était avant.
la source
De mon point de vue, une table des années distincte n'aurait de sens que si "l'année de sortie" n'est pas une année civile, mais par exemple un exercice financier qui peut s'étendre sur plusieurs années civiles (par exemple allant d'octobre à octobre).
Ce tableau contiendrait alors la définition (date réelle de début et de fin) de l'exercice
la source
Depuis http://en.wikipedia.org/wiki/Second_normal_form :
Vous n'avez pas indiqué si l'année fait partie de la clé candidate ou non, mais je ne suis pas sûr que cela soit important, car dans les deux cas, 2NF serait satisfait en ce qui concerne l'année.
Sur le plan pratique, c'est une mauvaise idée de séparer l'année pour toutes les raisons que vous avez énumérées.
la source
Je n'aime pas l'argument contre la table séparée en raison de sa taille ou du fait qu'elle contiendra des lignes inutilisées. Même si vous mettez 1000 ans dans ce tableau, la taille sera négligeable.
Cela dit, je ne pense pas que la table soit nécessaire. Quel est l'intérêt d'avoir un tableau séparé pour l'année? Ces données sont déjà dans la table principale et vous ne sauvez absolument rien en créant une deuxième table.
L'argument peut être différent pour une table de calendrier, où chaque ligne représente un jour et peut avoir d'autres attributs (jour de la semaine, décalage UTC, qu'il s'agisse d'un jour férié, etc.).
Mais l'année seule? Non, je ne vois aucun avantage du tout ... Et comme d'autres l'ont souligné, demandez-leur pourquoi ils pensent que c'est plus normalisé? Ou ce qu'ils gagnent? Si vous essayez d'écrire des requêtes comme
Au lieu de
Ensuite, j'essaierais de vous convaincre que ce dernier est bien meilleur pour les performances (en supposant que dt est indexé) et le stockage. Si la simplicité du codage est primordiale, je dirais qu'une colonne calculée persistante serait meilleure qu'une autre table.
la source
Je suis totalement d'accord avec la réponse de Catcall, sauf sur un point: "l'année" n'est peut-être pas toujours une valeur primitive, mais je suppose que c'est plus un concept de logique métier que de conception de base de données.
En gardant le même design, supposons que les années ne devraient être que les années autorisées pour la publication. De cette manière, vous ne traitez pas avec des valeurs numériques primitives, mais plutôt un sous-ensemble d'entre elles, et comme ce sous-ensemble n'a pas d'implémentation primitive, vous devez faire votre propre (un tableau séparé?) Et le référencer (avec un FK). De cette manière, nous parlons encore d'années, mais nous devons les gérer d'une manière différente, car elles ont changé leur signification conceptuellement. Cependant, ils sont toujours "l'année de sortie", mais conceptuellement différents en termes de ce que cela signifie pour quelqu'un dans la connaissance du domaine.
Pour ce cas spécifique, je répète que la réponse de Catcall est correcte, mais je voulais juste le souligner. (Désolé, nous n'avons pas encore assez de représentants pour commenter.)
la source