Je souhaite supprimer la redondance dans les champs de la table dans la design de ma database

J'ai 2 tables:

Maître des étudiants :

Id, Prénom, Nom de famille, email, N ° de téléphone, Countryid, stateid, cityid, Profilepicurl, le sexe, Dateofbirth.

CoachMaster :

Id, Prénom, Nom, email, N ° de téléphone, Paysid, état, cityid, Profilpicurl, genre, Dateofbirth, Langue.

Maintenant, vous remarquerez peut-être que ces 2 tables ont des champs communs, sauf 1 champ supplémentaire, par exemple Language in coachmaster .

Je pense à faire une seule table qui comprend de tous les champs de la table à savoir ce UserMaster (contient à la fois StudentMaster et CoachMaster) comme ceci:

UserMaster :

Id, rest tous les champs communs, Langue (du maître de l'entraîneur)

J'ai discuté avec un de mes amis qui est un développeur expérimenté et ce qu'il m'a dit de créer une table séparée seulement et il m'a montré 2 scénarios ci-dessous 2 pour créer 2 tables séparées :

  1. Si j'ai 1 table commune seulement qui est UserMaster et si à l'avenir je veux append 2 champs supplémentaires dans le maître d'entraîneur alors cette structure serait mauvaise.

  2. Si j'ajoute ces 2 champs supplémentaires nécessaires pour l'entraîneur dans UserMaster et si je veux juste des détails spécifiques d'étudiant alors ces 2 champs supplémentaires (ajoutés dans mon 1er point pour l'entraîneur) seront tirés aussi sans nécessité.

Remarque : D'autres scénarios peuvent également exister avec une seule table conservant les détails de l'entraîneur et de l'élève.

En dehors de cela ce que mon ami m'a dit que je ne suis pas la règle de normalisation ici et si j'ai une seule table qui est seulement usermaster alors pour identifier quel user est étudiant et quel user est tuteur je devrais toujours utiliser joindre c'est check est la table Userinrole que je vais maintenir comme ceci:

Rôle principal: ID, nom (valeur: étudiant, entraîneur)

UserInRole: RoleId (Référence à RoleMaster Id), UserId (stocker soit Studentid ou CoachId)

C'est comme ça que je devrais toujours find si c'est un étudiant quand j'aurais un identifiant .

Donc, quelqu'un peut-il m'aider à me guider sur la façon de créer une bonne structure qui résoudra ces 2 scénarios et évitera la création inutile de champs dupliqués dans ces deux arrays?

Vous pourriez certainement maintenir une table pour l'étudiant et l'entraîneur, mais, comme vous l'avez remarqué vous-même, ceci a des problèmes de maintenabilité. Cependant, il y a une faille dans votre parsing (ou celle de votre ami). Si vous avez une seule table avec un indicateur indiquant le type d'user ('S' ou 'C', par exemple) avec une table de search comme ceci:

ID Name <other> == ==== ======= S Student ... C Coach ... 

Une reference FK du champ indicateur dans la table Utilisateurs à cette table appliquerait la règle qu'un user doit être l'un ou l'autre et rien d'autre. Cependant, les requêtes n'auront pas toujours à se joindre à cette table. Le système vérifie que la valeur du FK existe dans cette table lorsque vous effectuez une insertion de la table Utilisateurs ou une mise à jour qui a modifié la valeur de ce champ indicateur. Dans le cas contraire, les requêtes ne rejoindraient cette table que si elles souhaitaient récupérer d'autres données.

Cela dit, à less que vous sachiez que votre design sera très stable pendant un certain time, je proposerais un design supertable-sous-table. Une réponse plus détaillée à une question similaire peut être trouvée ici:

Concevoir des relations autour d'une structure d'inheritance

Dans votre cas, la table générique ou super-maître ressemblerait à votre table actuelle de StudentMaster avec l'ajout d'un champ MasterType:

 create table Masters( ID int not null auto_generated primary key, ... MasterType char( 1 ) not null, ... constraint FK_Masters_Type foreign key( MasterType ) references MasterTypes( ID ), constraint UQ_Masters_Type unique( ID, MasterType ) ); 

Le FK force l'input à être définie en tant qu'étudiant ou entraîneur. Alors la table de StudentMaster serait simple car elle n'ajoute aucun nouvel atsortingbut au maître générique:

 create table StudentMasters( MasterID int not null primary key, MasterType char( 1 ) check( MasterType = 'S' ), constraint FK_StudentMasters_Master foreign key( MasterID, MasterType ) references Masters( ID, MasterType ) ); 

La vérification signifie que seuls les Etudiants peuvent être insérés dans cette table. Le FK signifie que l'ID doit correspondre à une input dans la table Masters et doit également être défini en tant qu'étudiant. Les valeurs d'ID des Etudiants qui ont été définis comme Coach (ou n'importe quel type futur possible) ne peuvent pas être stockées dans la table StudentMasters.

La table CoachMasters serait la même sauf qu'elle définirait le champ Language et la vérification serait "MasterType = 'C'".

Vous avez maintenant des options pour referencer les maîtres d'autres tables. Pour les FK qui se réfèrent à un Master, quel que soit le type, la reference peut être définie dans la table Masters. Si cela ne peut être, disons, qu'un Coach (CoachedBy), la reference peut être faite à la table CoachMasters. Ainsi, la valeur ID d'un étudiant ne peut jamais être accidentellement insérée dans ce champ. La même chose avec des references qui doivent se référer uniquement aux étudiants.

Une autre suggestion: devant cette table avec deux vues, CoachMasters et StudentMasters (renommer les tables à autre chose). Ensuite, votre application peut get des informations sur l'entraîneur ou l'étudiant sans même connaître la structure sous-jacente. Les triggersurs sur les vues permettront à toutes les opérations de parcourir les vues. Cela vous permet de modifier la disposition physique des arrays en cas de besoin. Redéfinissez simplement les vues et les triggersurs et le code de l'application n'a pas besoin d'être modifié. Cette astuce peut augmenter considérablement la maintenabilité de votre database.

SQL ne fournit pas un très bon support pour les relations "one-of". Il y a des methods, mais elles ont tendance à être un peu maladroites.

Parce que vous pensez aux "users" en plus des "étudiants" et des "entraîneurs", il semble que vous ayez une autre entité. Les «users» sont soit des «étudiants» ou des «entraîneurs».

Je pense que j'aborderais votre problème de deux façons.

Les deux commencent par une table Users , avec tous les champs des étudiants. C'est la key primaire pour les users, les étudiants et les entraîneurs. Tous les users sont considérés comme des étudiants, sauf s'ils ont des preuves d'être un coach. Quelle est cette preuve?

Une possibilité est une colonne de type dans la table Users avec les champs supplémentaires nécessaires. C'est souvent une approche très raisonnable de ce problème.

La seconde est une table d'addition Coaches avec une key primaire d'un CoachId qui est aussi une key étrangère à UserId . Cela contient les informations supplémentaires sur les entraîneurs. De plus, cela facilite la mise en place de relations de foreign keys là où c'est nécessaire.