web-dev-qa-db-fra.com

Expliquer 2NF vs 3NF avec un exemple

J'ai un problème avec la deuxième forme normale (2NF) et je n'ai pas pu le résoudre en utilisant Google. Cela me rend fou parce que je suis professeur et je ne veux pas enseigner de mauvaises choses à mes élèves.

Ayons une table avec 5 champs.

Gradations = {StudentName, SubjectCode, SubjectName, #Exam, Grade}

Les dépendances sont de cette façon:

StudentName, SubjectCode, #Exam -> Grade

SubjectCode -> SubjectName

SubjectName -> SubjectCode

Par conséquent, la clé candidate 1 est {StudentName, SubjectCode, #Exam} et la clé candidate 2 est {StudentName, SubjectName, #Exam}.

Les attributs principaux sont {StudentName, SubjectCode, SubjectName, #Exam} et les attributs non premiers sont Grade

Selon la définition de la deuxième forme normale, un attribut non premier ne peut pas dépendre d'une partie d'une clé candidate. Le seul attribut non premier (Grade) ne dépend pas d'une partie d'une clé candidate, ce tableau semble donc en 2NF.

Le problème est que je pense que quelque chose ne va pas (et je peux me tromper). Je pense que les sujets devraient avoir leur propre table.

Notes = {StudentName, Subject Code, #Exam, Grade}

Subjects = {Subject Code, SubjectName}

Mais 2NF ne produit pas cela. 3NF concerne les dépendances entre les attributs non premiers, il ne produit donc pas cela non plus. Mais il me semble que c'est le bon résultat, car il n'y a pas de redondance.

Je suppose que si l'attribut non premier était défini comme "attribut qui n'est pas une clé candidate", 2NF produirait le résultat souhaité. Mais j'ai vérifié cela encore et encore et l'attribut non premier est défini comme "attribut qui n'appartient pas à une clé candidate".

Qu'est-ce que je fais mal?

13
finsalscollons

Votre relation est en 3NF, (et pas seulement en 2NF), car comme vous le dites, le seul attribut non premier est Grade, qui n'apparaît que sur le côté droit de vos FD.

La relation n'est pas dans BCNF, car le côté gauche des deux petits FD n'est pas une super-clé.

Vous pouvez cependant décomposer sans perte la relation avec (SubjectCode, SubjectName) et soit (StudentName, SubjectCode, #Exam, Grade) ou ( StudentName, SubjectName, #Exam, Grade)

Cette décomposition vous donne deux relations BCNF et préserve toutes les dépendances fonctionnelles. Ce n'est pas toujours possible (vous pouvez toujours décomposer une relation avec 3NF, mais pas nécessairement avec BCNF).

2NF

Si vous voulez un exemple de 2NF (et non de 3NF), votre relation doit contenir des dépendances transitives.

Par exemple, supposons que vous ayez une colonne Score. Score intuitif-> Note car tous les examens avec le même score devraient obtenir la même note (ce serait plutôt injuste autrement), mais notez que nous ne pouvons pas dire Grade-> Score car plusieurs scores peuvent avoir la même note (11% et 12% serait probablement "Échec", par exemple).

Maintenant, votre relation est:

Notes (StudentName, SubjectCode, SubjectName, #Exam, Score, Grade)

et vous avez une nouvelle forme de redondance puisque chaque fois que vous entrez un résultat avec le même score qu'un autre enregistrement de notes, vous devez également répéter la note correspondante. Pour vous rendre à 3NF vous pourriez donc vous décomposer en

ScoreGrades (Score, Grade)

avec Score comme clé, et

Scores (StudentName, SubjectCode, SubjectName, #Exam, Score)

9
beldaz

Vous avez raison dans tout ce que vous dites. Subject Code, SubjectName doivent aller dans leur propre table afin d'appliquer les dépendances souhaitées. C'est un bon exemple des raisons pour lesquelles 2NF et 3NF ne sont pas suffisants pour produire de bonnes conceptions de base de données - vous avez plutôt besoin de Boyce Codd Normal Form (BCNF).

Le 2NF et le 3NF sont remplacés par le BCNF, ce qui rend pratiquement obsolètes ces NF moins importantes *. BCNF est le plus important et sans doute le plus simple à expliquer et à appliquer. En tant que professeur, je vous suggère de passer plus de temps sur BCNF et moins sur 2NF et 3NF. Si une table satisfait aux exigences de BCNF, elle satisfait également 2NF et 3NF également.


* 3NF n'est pas la forme normale préservant les dépendances la plus élevée. La forme normale de la clé élémentaire (EKNF) est. À proprement parler, c'est EKNF, et non BCNF, qui rend le 3NF obsolète, mais EKNF est injustement négligé et la plupart des manuels et des cours ne le mentionnent même pas. Ce qui revient à la même chose est de concevoir en BCNF puis de vérifier que toutes les dépendances souhaitées et toutes les autres règles d'intégrité peuvent être correctement appliquées - sinon, modifiez la conception. Aucune des NF n'est une solution complète à l'intégrité des données, mais BCNF est généralement le plus proche et est le plus facile à expliquer et à utiliser.

4
nvogel

Le seul attribut non premier (Grade) ne dépend pas d'une partie d'une clé candidate, ce tableau semble donc en 2NF.

C'est en 2NF.

Le problème est que je pense que quelque chose ne va pas (et je peux me tromper). Je pense que les sujets devraient avoir leur propre table.

Il n'y a aucune raison de s'attendre à ce que les sujets aient leur propre table pour une décomposition de la table d'origine en 2NF. Vous confondez une vague notion de "devrait" avec ce que vous donne réellement une forme normale particulière.

3NF concerne les dépendances entre les attributs non premiers, il ne produit donc pas cela non plus.

"3NF concerne les dépendances entre des attributs non premiers" n'est pas une définition correcte de 3NF donc "donc il ne produit pas cela non plus" n'est pas une conclusion valable. Bien que l'application d'une définition réelle montre que la table est en 3NF, aucune table d'élève n'est nécessaire. Mais encore une fois, il n'y a aucune raison de s'attendre à ce qu'il y en ait.

Mais il me semble que c'est le bon résultat, car il n'y a pas de redondance.

Encore une fois, la "redondance" est d'une vague inutile, donc vos attentes "parce que" et la table des étudiants ne sont pas valables. Différentes formes normales sont exemptes et soumises à des types particuliers de anomalies et "redondance" associée. Mais d'autres "redondances" non traitées par la normalisation peuvent subsister.

Cette table n'est pas en BCNF, car elle contient des FD qui ne sont pas en dehors des CK. La décomposer par BCNF conduit à avoir la table des élèves. BCNF est la forme normale la plus élevée pour traiter les JD (joint dependencies) qui accompagnent les FD. Cependant, d'autres JD peuvent être problématiques (c'est-à-dire non "impliqués par les CK") et doivent être supprimés par normalisation à 5NF.

PS Le tableau d'origine satisfait également le FD {StudentName, SubjectName, #Exam} -> Grade.

Les dépendances sont de cette façon:

Qu'est-ce que cela est censé signifier? Ce n'est pas clair.

Voulez-vous dire: "Ce sont tous les FD non triviaux qui détiennent"? Non, car ils impliquent le quatrième. "Voici quelques FD qui tiennent"? Non, cela signifie que les FD dans la fermeture transitive tiennent, mais cela ne dit pas que les autres ne pas tiennent, pourtant vous avez pu déterminer les CK. "Les FD qui tiennent sont exactement ceux de la fermeture transitive de ceux-ci"? Si vous signifiiez cela, vous ne le feriez que know que si vous l'aviez montré, c'est-à-dire que vous auriez dû trouver cette fermeture (généralement, via une couverture minimale/canonique) et a ensuite montré qu'il n'y a pas d'autres FD; as tu? Quoi qu'il en soit, ce que vous avez écrit ne signifie pas cela. J'espère donc que vous ne raisonnez pas à fond sur la situation FD & CK.

2
philipxy

Je ne dirai pas combien de temps s'est écoulé depuis que j'ai appris tout cela pour la première fois. Mais je me souviens que j'avais un prof qui, après nous avoir enseigné consciencieusement le sens propre de "dépendance fonctionnelle" et "attribut non premier" et tous les autres mots à la mode, nous a posé une série de questions simples à poser pour voir si une normale particulière formulaire a été atteint. Voyons si je me souviens aussi loin ...

Nous avons identifié la ou les clés candidates, nous posons donc cette question sur les attributs non premiers restants. Dans ce cas, il n'y en a qu'un: grade.

Quelles sont les informations minimales absolues dont nous avons besoin pour identifier de façon unique la note? Nous devons connaître l'étudiant, le sujet et l'examen en cours. Très bien, c'est l'une des clés candidates.

MODIFIER: V V V

Mais la réponse aurait tout aussi bien pu être le nom de l'étudiant, le nom du sujet et l'examen. Cela correspondrait à la deuxième clé candidate.

En supposant que SubjectCode et SubjectName sont tous deux des clés candidates pour l'entité Subject, il n'y a aucune raison d'avoir ces deux champs ici. Une référence unique à une ligne du tableau Sujets suffit amplement. Nous pouvons donc nous débarrasser du champ SubjectName en toute sécurité sans sacrifier l'intégrité du modèle.

Cependant, dans ma réponse d'origine, dans mon désir de montrer un autre niveau de normalisation, j'ai ignoré que SubjectName avait été utilisé dans une clé candidate et je l'ai considéré comme un autre attribut non premier. Je suppose que c'était tellement évident pour moi que c'était un domaine inutile, je pensais que ce serait tout aussi évident pour tout le monde et puisque de toute façon nous nous sommes débarrassés du champ, qu'importe?

Mais au lieu de supprimer cette partie de la réponse, je vais la conserver pour comparaison.

FIN DE MODIFICATION: ^ ^ ^

Quelle est l'information minimale absolue dont nous avons besoin pour identifier de manière unique le nom du sujet?

SubjectName dépend uniquement de SubjectCode - un sous-ensemble de la clé candidate. Donc, ce tuple n'est pas en 2nf. SubjectCode doit être la clé primaire d'une table Subjects, c'est donc l'emplacement approprié pour placer SubjectName. Supprimez-le de ce tuple et il est maintenant en 2nf.

Si nous posons la question d'un attribut et que la réponse n'est pas tout ou partie de la clé candidate, alors le Tuple n'est pas en 3nf. Mais ce tuple est également trivialement en 3nf et au-delà, car nous n'avons plus de champs pour poser des questions. ;)

Note: quand nous disons "normaliser", nous faisons référence à un processus qui est appliqué à une entité logique. Comme le Tuple fourni semble être la définition d'une entité appelée "grade", nous pouvons alors le normaliser. Cependant, à un moment donné, j'ai dit "ce tuple n'est pas en 2nf", ce qui aurait dû être plus correctement, "cette entité n'est pas en 2nf." Je m'excuse si cela a causé de la confusion.

2
TommCatt

Vous avez raison, le sujet nécessite sa propre table. Si vous choisissez l'une de vos clés candidates, soit subject_code ou subject_name devient une clé candidate non principale. Vous supprimez ensuite le champ des sujets non principaux du tableau des notes.

Vous avez une dépendance fonctionnelle sur le sujet pour lequel vous avez deux identifiants uniques. Ceci est démontré par la dépendance transitive entre subject_code et subject_name. Cela indique la nécessité de créer une table contenant ces deux champs et de supprimer l'un de ces champs de toutes les autres tables. Cette table pourrait bien avoir des colonnes dépendantes supplémentaires, bien que je n'en vois aucune dans cet exemple. En 3ème forme normale que vous avez sélectionnée.

la note dépend des trois autres champs (clé candidate) dans le nouveau tableau de notation. Comme indiqué ci-dessus, vous devez sélectionner l'un des champs candidats pour le tableau des sujets. Normalement, ce serait une valeur de code si elle est disponible car elles ont tendance à être plus stables. Le modèle résultant est en 3nf car tous les champs non clés dépendent entièrement des champs de la clé primaire.

Une analyse plus approfondie du problème (exigences) est susceptible de produire un tableau de sessions sur lequel les notes sont appliquées. Il est peu probable que le modèle actuel couvre un étudiant qui répète un cours. Cela serait traité dans une leçon ultérieure.

Les étudiants sont également susceptibles de devenir une table distincte car il est possible d'avoir plusieurs étudiants portant le même nom. Ce problème serait probablement résolu par l'ajout d'une clé primaire synthétique (numéro d'étudiant?).

subjects --->  sessions ---+--> grades
students  -----------------+
0
BillThor