web-dev-qa-db-fra.com

Une table excessive viole-t-elle les règles de normalisation?

Voici un exemple de quelques tables qui existent dans une base de données où je travaille. Les données ne concernent pas réellement les écoles, mais la structure est identique.

Il y a quatre tableaux:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Club **
Club Id, School Id, ClubType Id

** Student **
Student Id, Name, Club Id

Sachant que la table Club n'aura jamais de colonnes supplémentaires (car les données réelles ne concernent pas réellement les clubs scolaires),

Je pense qu'un design nettement meilleur, en éliminant la table Club pour éviter les jointures, serait:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Student **
Student Id, Name, School Id, ClubType Id

Edit: Nous savons également que chaque identifiant de club ne peut avoir qu'un seul type. La relation entre Club et ClubType est de 1 à 1.

Ma question est la suivante: le premier exemple viole-t-il une règle connue de normalisation de base de données ou un autre principe mathématique? Ou s'agit-il simplement d'une mauvaise conception?

8
Burgan

En adoptant la solution que vous proposez, vous perdez des informations de la base de données. La solution existante indique quels clubs peuvent exister dans une école particulière indépendamment du fait que quiconque se trouve réellement dans ce club à un moment donné. La solution proposée exige que quelqu'un rejoigne le club avant que le club ne soit créé (c'est-à-dire avant qu'une ligne ne soit écrite dans la base de données).

Comme implication pratique, pensez aux fiches d'inscription. C'est la veille du début du trimestre. Le directeur veut une feuille d'inscription sur le tableau d'affichage pour chaque club afin que les étudiants puissent se joindre. Il serait inutile d'imprimer une feuille pour tous les types de clubs et de laisser les étudiants rejoindre des clubs qui n'existeront jamais dans cette école. Aujourd'hui, avant le début du trimestre, il n'y a pas d'étudiants, donc la solution que vous proposez ne fonctionnera pas. La solution existante permet cependant au directeur d'école d'offrir, disons, un club de football mais pas un club de water-polo.

Je me rends compte que vous utilisez l'analogie école/club comme proxy pour votre situation réelle, et vous allez devoir traduire tout ce que je dis sur le problème réel et que les commentaires que je vais faire peuvent ne pas s'appliquer. C'est le prix à payer pour les analogies. Si votre "école" actuelle peut choisir parmi tous les "types de clubs" tout le temps, alors la solution que vous proposez est adéquate.

Ou s'agit-il simplement d'une mauvaise conception?

Ce n'est pas une mauvaise conception. Ce n'est pas non plus un bon design. C'est une conception qui met en œuvre certaines opportunités mais en exclut d'autres. Il a été rédigé pour des raisons auxquelles nous n'avons pas accès. Il a été rédigé avec les connaissances disponibles à l'époque. Il a probablement passé un grand nombre de tests et une utilisation active de la production.

Maintenant, le monde a peut-être évolué depuis. Les règles commerciales peuvent avoir changé; la compréhension de l'équipe de mise en œuvre s'est peut-être améliorée. Cette conception peut avoir une caractéristique de performance qui n'est pas acceptable sur votre matériel avec votre charge de travail compte tenu de vos données. Il peut être approprié de modifier cette conception.


La normalisation concerne la façon dont les colonnes non clés dépendent des colonnes clés dans une seule table. Il montre comment vous pouvez modifier le schéma afin de changer une seule valeur dans le monde réel mettra à jour une seule colonne dans une seule ligne dans la base de données. Il n'a rien à dire sur la mise en œuvre de scénarios à partir du problème du monde réel à portée de main.

Je comprends que votre table Étudiant actuelle signifie "une personne en tant que membre d'un club". Pour cela, la clé primaire sera {id étudiant, id club}. Dans votre implémentation actuelle, le tableau n'est pas normalisé car le nom dépend uniquement de l'ID de l'élève et non de l'ID du club. La solution normalisée serait de changer la sémantique de la table Student en "A person" (colonnes id étudiant, nom) et de créer une nouvelle table ClubMember avec les colonnes {id étudiant, id club}.

La relation entre Club et ClubType est de 1 à 1.

J'en doute. Quelles sont les valeurs possibles de ClubType? Peut-être "soccer" ou "yoga"? Je pense que de nombreuses écoles aimeraient avoir un club de football. Peut-être

Each Club     is-this-schools exactly one   ClubType  
Each ClubType is-offered-in   zero or more  Club

En tant que ERD:

ClubType --< Club >-- School
19
Michael Green

le premier exemple viole-t-il une règle connue de normalisation de base de données ou un autre principe mathématique? Ou s'agit-il simplement d'une mauvaise conception?

Ni. Il ne présente aucun défaut évident de normalisation ou de bonne conception.

Il modélise judicieusement les propositions comme suit:

  • Il y a une école nommée 'School1'.
  • Il existe un ClubType nommé 'Spanish Club'.
  • School1 a un club espagnol.
  • Il y a un étudiant nommé "Fred" à School1 qui est membre du Club espagnol là-bas.

La seule chose étrange à propos de ce modèle est qu'un étudiant ne peut être membre que d'un seul club. Cela a du sens, ce serait juste une règle inhabituelle pour une vraie école.

De mon point de vue, votre table d'élèves est "étrange" ... la plupart des écoles ne limiteront pas les élèves à 1 club.

Je rendrais la table des élèves aussi "courte" que possible

** Étudiant **
Identifiant étudiant, nom

Même votre identifiant d'école de colonne est discutable, car vous auriez généralement la base de données entière pour UNE école - donc l'identifiant d'école est inconscient. Mais cela peut provenir de votre tentative d'utiliser un exemple - dans mon autre forum, nous donnons généralement l'indice d'utiliser le véritable "exemple" en cachant/anonymisant les données pour éviter le "piège" dans lequel vous êtes tombé.

Même si votre objectif est de réduire les jointures… ce sont les vraies clés d'une conception de base de données efficace (les "relations" dans le modèle de base de données relationnelle).

J'aurais donc au moins une table

** Cartographie des clubs étudiants **
Identifiant étudiant, identifiant du club

où la combinaison des deux colonnes est unique et clé. Cela permet aux étudiants d'être à la fois dans une langue et dans un club de sport - croyez-moi, ce genre d'étudiants existe ^^

Edit: votre disposition d'origine limite les étudiants à 1 club car votre disposition de table le dit

** Étudiant ** Identifiant étudiant, nom, identifiant du club

cette disposition exige généralement que l'ID étudiant (comme clé) soit unique - donc 1 étudiant = 1 ligne = 1 club tout le reste est très mauvais design de base de données (listant plusieurs identifiants de club dans la colonne ID du club peut-être séparés par des virgules deviendra un cauchemar lors de la construction sélectionne par exemple la liste des étudiants pour une liste de clubs)

1
eagle275

La deuxième conception ne prend pas en charge plusieurs clubs du même type dans la même école, selon l'application DB qui peut même être deux clubs qui existent à des moments différents (dans notre école, le journal des étudiants a cessé d'exister et a été redémarré).

En relation avec cela, il y a une multitude de choses que vous ne pouvez pas représenter ou qui seront maladroites:

  • clubs vides
  • personnes correspondantes pour les clubs
  • création d'un club (lié au club vide)
  • les étudiants étant membres de plusieurs clubs du même type à des moments différents
  • Vous pourriez, étant donné qu'un seul club existe à la fois, créer une table supplémentaire pour prendre en charge le nom du club, son représentant, etc. (maladroit, mais pas un problème)

Donc, la question: à quels enseignants supervisait les clubs dont cet élève faisait partie? est impossible dans la seconde formulation.

Cela signifie que les deux conceptions couvrent des relations différentes mais, étant donné 1: 1 entre (type de club, école) et (club), le second devrait convenir.

Les différences entre les solutions proposées ne sont pas liées à la normalisation AFAIU.

  • Ce que j'imaginerais comme pertinent pour la normalisation serait de ne pas mélanger le nom de l'étudiant et l'adhésion au club - mon intuition me dit que le fait d'avoir un tableau séparé représentant les "adhésions au club" composé de l'ID de l'étudiant, l'ID du club peut (en fonction des autres tables qui existent dans le DB) être plus durable en maintenant la base de données normalisée à l'avenir.
0
Sascha

Je vois d'autres problèmes avec cette structure de base de données particulière, mais pour répondre directement à la question OP,

Non, l'utilisation de tables de recherche telles que School et ClubType ne viole aucune règle de normalisation. Il s'agit d'une pratique assez standard pour créer des tableaux autour des valeurs id et avoir des valeurs de texte facilement lisibles dans une table de recherche.

Pour résoudre les problèmes que je vois dans la structure de la base de données,

Je pense que la table Club dans cet exemple ne devrait pas avoir de champ d'identification d'école et devrait avoir un champ de nom, car un nom de type de club et un nom de club peuvent être deux caractéristiques distinctes d'un club. De plus, le même club pourrait exister dans plusieurs écoles.

De plus, l'étudiant ne doit pas avoir de champ d'identification de club, car un étudiant peut appartenir à plusieurs clubs.

Enfin, cette base de données a en fait besoin de 2 tables supplémentaires pour gérer la relation plusieurs: plusieurs du club: école et élève: club

0
noname

Vous dites que ce n'est pas la vraie base de données, nous sommes donc réduits à deviner à quoi pourrait ressembler le vrai problème. Je comprends que vous ne souhaitiez peut-être pas divulguer des informations exclusives, mais ne pourriez-vous pas anonymiser le vrai problème? Quoi qu'il en soit, pour les besoins de la discussion, je vais en discuter comme si le problème que vous donnez était le vrai problème.

La première conception de la base de données est logique et est généralement bien organisée et normalisée.

Vous pouvez avoir n'importe quel nombre d'écoles. Cela a du sens s'il y a plusieurs écoles dans un district, comme 3 écoles élémentaires, 2 collèges et un lycée.

Il peut y avoir plusieurs types de clubs. Je ne suis pas sûr de ce qu'est un type de club, mais je pense peut-être "sports" vs "académique" vs "culturel".

Il peut y avoir de nombreux clubs au sein d'un type de club. Comme les clubs sportifs peuvent inclure le football, le baseball et le hockey.

Les clubs existent dans une école. Le lycée peut avoir un club de football alors que les écoles élémentaires n'en ont pas.

Un étudiant peut être membre d'un ou plusieurs clubs. Ou un étudiant ne peut-il être membre que d'un seul club? Si un étudiant peut appartenir à plusieurs clubs, le nom de l'étudiant est répété pour chaque club, ce qui est des données redondantes et erronées. Il devrait y avoir des tables séparées pour les étudiants, avec student_id et nom, et l'adhésion au club, avec student_id et club_id. Dans le cas improbable où un élève n'est autorisé à appartenir qu'à un seul club, la conception donnée est correcte.

Votre alternative proposée crée un certain nombre de problèmes.

  1. Il ne parvient pas à distinguer différents clubs au sein d'un type de club. S'il ne peut y avoir qu'un seul club de chaque type, alors d'accord, il n'y a pas de raison d'avoir un type de club et des tables de club séparés, les deux pourraient être combinés. Mais s'il peut y avoir plusieurs clubs dans un même type, vous avez jeté ces informations.

  2. En supposant que "type de club" et "club" sont la même chose, vous avez supprimé la possibilité de dire quels types de club/club existent dans chaque école. Il n'y a aucun moyen de dire que le lycée a un club d'échecs mais pas le lycée, par exemple.

  3. Comme pour la première conception, si un élève peut appartenir à plus d'un type de club/club, le nom de l'élève et l'identifiant de l'école sont répétés pour chaque club.

Franchement, je pense que le design original est meilleur. C'est imparfait, mais en mieux.

0
Jay