Conseils sur une conception de base, première conception de base de données

8

Je prends un cours pour devenir développeur Java.

Le cours implique l'utilisation de bases de données mais nous n'en concevons jamais vraiment, malheureusement.

La plupart du temps, nous obtenons des bases de données prédéfinies et nous devons implémenter du code dessus pour insérer, mettre à jour, lire ou supprimer des données.

Mais quand mon test final arrivera, il y a de fortes chances que je fasse quelque chose qui implique une base de données et donc je veux essayer d'en concevoir quelques-unes plus petites pour obtenir le coup d'une conception car j'ai remarqué qu'une bonne conception de base de données fait beaucoup de différence quand écrire le code pour travailler avec.

J'espère que ce type de questions est autorisé ici et que ce ne sera pas trop large.


Ceci est un petit design que j'ai fait pour quelque chose de simple comme clubset membersavec addresseset phonenumbers.

  • Il y aura plusieurs clubs.
  • Chaque club aura plusieurs membres (évident)
  • Un membre ne peut pas faire partie de plusieurs clubs
  • Un membre peut avoir plusieurs numéros de téléphone et adresses e-mail
  • Un membre ne peut avoir qu'une seule adresse
  • Une adresse peut appartenir à différents membres (couples ou frères et sœurs)

Mes plus grandes confusions:

  • Si je veux ajouter une colonne Clubdécrivant le propriétaire, qui sera également membre, quelle est la meilleure approche sans avoir le même membre répertorié deux fois?

  • Dois-je mettre toutes mes tables sur l'incrémentation automatique d'un identifiant ou serait-ce une mauvaise idée? (avantages / inconvénients?)

  • Si j'ajoute des clés étrangères dans l'onglet des clés étrangères, celles-ci correspondront-elles automatiquement à la bonne table ou dois-je également les ajouter aux colonnes? (voir photo 2)

  • Et ma question sans doute la moins intéressante du tout ... Est-ce que je mets les clés étrangères de phonenumberet emaildans leur table respective reliant à un person_Id ou dois-je mettre phoneNumber et les identifiants de courriel dans la table person?

(Mes excuses pour la langue des photos n'étant pas en anglais, j'espère que ce n'est pas trop un problème)

Conception

Clés étrangères

Vahx
la source

Réponses:

11

Réponses à vos questions individuelles

Si je veux ajouter une colonne Clubdécrivant le propriétaire, qui sera également membre, quelle est la meilleure approche sans avoir le même membre répertorié deux fois?

Si, comme indiqué dans vos spécifications a Person can be a Member of only one Club, et que vous souhaitez stocker cette donnée simplement comme vraie ou fausse , une option consiste à ajouter une BIT(1)ou une colonne BOOLEAN( TINYINT) au Persontableau, et vous souhaiterez peut-être appeler cette colonne IsClubOwner. De cette façon, vous pouvez enregistrer le fait qu'une personne déterminée est propriétaire d' un club exclusivement une fois. En dehors de cela, cette méthode permet également de conserver plusieurs personnes en tant que propriétaires de la même occurrence de club . Vous pouvez voir une représentation au niveau logique de cette approche dans la figure 1 .

Cependant, vous recherchez la meilleure approche et, selon mon expérience, une telle approche implique le développement d'une structure beaucoup plus extensible et polyvalente. À cet égard, suivez la progression d'un exercice de modélisation pour ces points et d'autres ci-dessous, dans les sections intitulées «Couvrir vos spécifications restantes», «Personne en tant que membre de plusieurs clubs» et «Membre et propriétaire en tant que types d'entités distinctes».

Dois-je mettre toutes mes tables sur l'incrémentation automatique d'un idou ce serait une mauvaise idée? (avantages / inconvénients?)

Si vous êtes confronté à une exigence explicite qui indique la définition d'une table avec une colonne de ces caractéristiques, et que cette colonne a une signification contextuelle valide ou sert un objectif particulier comme être un substitut pour une large clé naturelle (PK), alors oui, vous devez procéder de cette façon.

Sinon, si vous n'avez pas dit cette exigence, je considère que ce ne serait pas nécessaire car vous devez stocker et gérer une colonne supplémentaire vide de sens et (peut-être?) Également un INDEX supplémentaire dans votre base de données.

Comme d'habitude, vous devez analyser chaque cas ainsi que ses répercussions globales afin de décider comment continuer.

Si j'ajoute des clés étrangères dans l'onglet des clés étrangères, celles-ci correspondront-elles automatiquement à la bonne table ou dois-je également les ajouter aux colonnes?

À cet égard, mon conseil pour vous est de créer votre structure de base de données manuellement, de coder vos propres DDLdéclarations jusqu'à ce que vous compreniez bien le sujet. Si vous le faites, il vous sera plus facile de comprendre les processus que les outils graphiques exécutent «sous le capot».

Pour moi, par exemple, créer une déclaration comme celle-ci:

CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)

Est beaucoup plus instructif que d'utiliser des outils GUI pour exécuter ce type de tâches, surtout maintenant que vous construisez vos premières conceptions.

Et ma question probablement la plus noble de toutes ... Est-ce que je mets les clés étrangères de phone_numberet emaildans leur table respective en les reliant à person_idou devrais-je mettre phone_numberet email idsdans la table person?

Personnellement, je pense que cette question et toutes vos autres questions sont parfaitement valables et bien contextualisées .

Revenant aux aspects techniques qui nous concernent, cette enquête précise offre une bonne occasion de revoir les deux affirmations suivantes:

  • A Person can be reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber can be used to reach one-to-many People

Ainsi, on peut conclure qu'il existe une relation plusieurs-à-plusieurs entre Personet PhoneNumber, par conséquent, je suggère la création d'une table associative nommée PersonPhoneNumberpour représenter ladite relation dans votre base de données. Le PK de ce tableau doit être composé de deux colonnes différentes: PersonId(une clé étrangère [FK] pointant vers Person.PersonId) et PhoneNumber(un FK qui fait référence à PhoneNumber.Number). Pour une description logique de tout ce qui précède, voir la figure 1 .

En revanche, examinons les deux propositions qui suivent:

  • A Person can be contacted via zero-one-or-many EmailAddresses
  • An EmailAddress can be used to contact exactly one Person

Ensuite, oui, vous devez définir un référentiel FK à Personpartir du EmailAddresstableau, et ce tableau doit également avoir un PK composite, qui serait composé des colonnes PersonIdet Address. De cette manière, vous pouvez vous assurer que la même combinaison de EmailAddress.PersonIdet EmailAddress.Addressne peut être insérée qu'une seule fois.

Si vous souhaitez également vous assurer qu'un élément donné EmailAddres.Addresspeut être stocké dans une seule ligne, il vous suffit d'établir une CONTRAINTE UNIQUE pour cette colonne.

Modèles de données logiques proposés

Afin d'exposer mes suggestions plus clairement, j'ai inclus quatre modèles logiques IDEF1X [1] distincts qui sont illustrés dans les figures 1 , 2 , 3 et 4 . Je vais fournir une explication des fonctionnalités les plus pertinentes affichées dans chacun d'eux dans les sections correspondantes. Vous pouvez également télécharger depuis Dropbox un PDF qui intègre dans un même modèle la majorité des éléments en discussion.

Couvrant vos spécifications restantes

Relier les personnes et les adresses

Inspectons les deux assertions suivantes (légèrement reformulées) qui sont pertinentes pour les personnes et les adresses :

  • A Person can only have one Address
  • An Address can belong to different People (couples or siblings)

Ainsi, pour faire face à ces restrictions, vous pouvez choisir d'implémenter un modèle de données similaire à celui que vous pouvez voir dans la figure 1 .

Fig. 1. Modèle de données des clubs et membres - premières spécifications

En tenant compte du modèle référencé, vous devez suivre les étapes suivantes:

  1. Créez une table appelée PersonAddresscorrection d'une relation entre Personet Address. Définissez les colonnes PersonIdet AddressIdle PK composé de ce tableau.

  2. Configurez une CONTRAINTE UNIQUE pour la PersonAddress.PersonIdcolonne pour vous assurer qu'une valeur spécifique peut être insérée dans au plus une ligne de ladite table. Au niveau logique, cette circonstance implique qu'elle PersonAddress.PersonIdest devenue une CLÉ ALTERNATIVE [2] .

  3. Si la valeur de AddressIddans une PersonAddresstentative d'insertion déterminée n'a pas déjà été stockée, laissez l'insertion continuer, sinon, lorsqu'une telle valeur existe déjà dans une ligne, vous devez vérifier que (a) celui PersonIdqui s'est enregistré qui AddressIdest également enregistré en tant que Marriage.WifeIdsi le PersonIdest un mâle (donnée dérivée via le Person.GenreCode) ou (b) qui PersonIdest le Marriage.HusbandIdlorsque le PersonIdest une femelle (dérivé en vertu de Person.GenreCode, également). Si l'une de ces conditions est remplie dans la situation appropriée, vous devez laisser l'insertion se poursuivre.

  4. Si les conditions ci-dessus ne sont pas remplies, il y a encore une chance qu'une PersonAddresstentative d'insertion réussisse. Vous devez vérifier que la PersonIdvaleur impliquée dans ladite tentative d'insertion partage au moins une Progeny.ParentIdavec celle PersonIdqui a déjà enregistré le PersonAddress.AddressId. Si cette condition est remplie, cela signifie qu'ils sont stockés comme Siblingsdans la base de données, donc cet INSERT doit réussir.

Comme dans toute implémentation de base de données relationnelle, vous devriez sérieusement envisager d'exécuter vos DMLopérations dans ACID Transactions afin de pouvoir protéger l' intégrité et la cohérence des données avec lesquelles vous travaillez.

Assister aux exigences que vous avez ajoutées dans les commentaires: adresses et numéros de téléphone desservant à la fois les clubs et les personnes

À condition que vous souhaitiez donner la possibilité aux adresses et aux numéros de téléphone de servir à la fois les personnes et les clubs , vous pouvez utiliser une relation supertype-sous-type . Voici une réponse dans laquelle je donne un traitement plus détaillé à ce type de structures, au cas où vous seriez intéressé.

Dans le scénario actuel, vous pourriez définir Personet en Clubtant que sous-types d'une nouvelle entité nommée Party, un terme couramment utilisé dans les cercles juridiques pour représenter (a) une personne ou (b) un groupe de personnes (comme indiqué dans le sens n ° 6 ). Avec cette méthode, les relations entre Addresses(ou PhoneNumbers) et Peopleet Clubsseraient définies par Partyle biais du supertype. Voir la figure 2 pour une description de cette suggestion.

Fig. 2. Modèle de données des clubs et membres - Deuxième spécifications

Fête et adresse

On peut donc lire dans ce nouveau modèle que:

  • A Party keeps zero-one-or-many Addresses
  • An Address is kept by one-to-many Parties

Ainsi, il existe une relation plusieurs-à-plusieurs impliquant Partyet Addressqui est exprimée par le biais de l' PartyAddressentité.

Fête et numéro de téléphone

De plus, nous pouvons interpréter cela:

  • A Party is reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber is used by one-to-many Parties

C'est pourquoi j'ai ajouté l' PartyPhoneNumberentité qui décrit l'association plusieurs-à-plusieurs qui prend effet entre les types d'entité Partyet PhoneNumber.

Fête et club ou personne

Ensuite, on peut également lire que:

  • A Party is either a Club or a Person

Par conséquent, Partyfournit une connexion de deux Clubs ou People de Addresses(ou PhoneNumbers).

Personne en tant que membre de plusieurs clubs

Comme @aldwinaldwin le mentionne dans sa réponse, si vous souhaitez fournir la fonctionnalité permettant à une personne d'être membre de plusieurs clubs , vous pouvez inclure une table appelée ClubMemberqui agirait comme une autre relation de plusieurs à plusieurs, cette fois, naturellement , interconnexion Personet Club.

Je vais ajouter à ce qui précède que ce tableau peut également être utile dans le but de stocker toute personne concrète en tant que propriétaire de plusieurs clubs , grâce à l'inclusion de la IsClubOwnercolonne booléenne déjà mentionnée . En fait, on peut dire que ce nouveau tableau est la représentation d'un type d'entité intégrale à part entière.

Comme le montre la figure 3 , un tel tableau nécessite un PK composite composé des colonnes ClubIdet MemberId(un nom de rôle [3] donné à PersonId), et ces colonnes doivent être définies également comme des FK pointant, de manière correspondante, vers Clubet Person.

Fig. 3. Modèle de données des clubs et membres - Personne en tant que membre de plusieurs clubs

Une structure plus adaptable

En utilisant ce paramètre, vous pouvez également respecter la règle initiale qui le stipule a Person can be a member of only one Club, mais il vous suffit d'ajouter une CONTRAINTE UNIQUE à la MemberIdcolonne, de sorte qu'une certaine valeur puisse être entrée en une seule fois. Donc, comme vous pouvez le constater, cette structure est beaucoup plus adaptable que celle illustrée à la figure 1 , car en supprimant la CONTRAINTE UNIQUE (ou INDEX), vous ouvririez la fonctionnalité susmentionnée de permettre à une personne de devenir membre de différents clubs au en même temps.

Membre et propriétaire en tant que types d'entité distincts

Comme vous le savez, le stockage de plusieurs faits sur le rôle joué par une personne en tant que propriétaire d'un club - outre sa simple existence dans un attribut vrai ou faux - peut être très avantageux. Par exemple, vous pouvez garder la date où une certaine personne est devenu le propriétaire d'un club , vous pouvez donc gérer cette situation en introduisant un type d'entité distincte appelée ClubOwner, tel que présenté dans la figure 4 .

Fig. 4. Modèle de données des clubs et membres - Membre et propriétaire en tant que types d'entités distinctes

Une fois que vous avez construit une table basée sur ce nouveau type d'entité, vous pouvez ajouter les colonnes d'ajustement qui représentent les caractéristiques qui entrent en jeu exclusivement lorsque a Personest la Ownerde a Club. Comme illustré, ce tableau contiendrait un PK composé des colonnes FK référençant Person.PersonIdet Club.ClubId, de cette façon, n'importe quelle combinaison de ClubOwner.OwnerId(ou ClubOwner.PersonId, si vous préférez) et ClubOwner.ClubIdpeut être inséré en une seule occasion.

Bien sûr, avec cette configuration, vous pouvez toujours dériver sous forme booléenne si a Personest le Ownerd'un particulier Clubà l'aide d'une requête qui retourne une valeur scalaire qui peut être évaluée à vrai ou faux .


Remarques

1. La définition d'intégration pour la modélisation de l'information ( IDEF1X ) est une technique de modélisation de données hautement recommandable qui a été définie comme norme en décembre 1993 par le National Institute of Standards and Technology ( NIST ) des États-Unis . Il est solidement basé sur (a) certains des articles théoriques rédigés par l' auteur du modèle relationnel , c'est-à-dire le Dr EF Codd ; sur (b) la théorie Entité-Relation , développée par le Dr PP Chen ; et également sur (c) la technique de conception de bases de données logiques , créée par Robert G. Brown . Il convient de noter que IDEF1X étaitformalisé par une logique de premier ordre .

2. Une TOUCHE ALTERNATIVE est un attribut (ou une combinaison d'attributs) qui contient des valeurs qui identifient de manière unique une occurrence d'entité mais qui n'a pas été choisie comme PK du type d'entité pertinent; chaque type d'entité peut avoir zéro, une ou plusieurs CLÉS ALTERNATIVES. Dans un modèle IDEF1X, ils sont indiqués comme «AK» plus son numéro respectif, par exemple AK1, AK2, etc. Ils sont généralement implémentés dans une structure SQL DDL via une CONTRAINTE UNIQUE (ou un INDEX UNIQUE ).

3. Les noms de rôle sont des dénotations (ou alias) attribuées aux attributs FK afin d'exprimer la signification qu'ils détiennent dans le cadre de leur entité respective. Leur utilisation est recommandée depuis 1970 par le Dr Codd dans son article fondateur intitulé «Un modèle relationnel de données pour les grandes banques de données partagées» . Pour sa part, IDEF1X - maintenir la fidélité en ce qui concerne les pratiques relationnelles - préconise également le nommage des rôles.

MDCCL
la source
2
  1. Si un propriétaire est toujours membre de son club. Ajoutez ownerId à la table Club et placez-y le personId du membre propriétaire.
  2. L'auto-incrémentation d'un identifiant est bonne. Vous pouvez ajouter un autre champ «code», là vous mettez le code des membres sur la carte de club là-dedans.
  3. Devrait être automatiquement ok (je pense)
  4. Mettez personId dans les numéros de téléphone et le tableau des e-mails.

... Vous ne pouvez pas être membre de plusieurs clubs? Si vous le pouvez, créez une table ClubMember avec clubId et personId. De cette façon, vous pouvez connecter une personne à plusieurs clubs.

aldwinaldwin
la source
1
Que faire si je veux que mon club ait un numéro de téléphone? dois-je également clubIdsaisir le numéro de téléphone et laisser le club ou la personne à zéro?
Vahx
Je ne séparerais pas trop tous les objets (normalisation des données). Il suffit de mettre 1 numéro de téléphone sur la table du club. La normalisation est bonne, mais une normalisation excessive peut provoquer des problèmes.
aldwinaldwin
1
mais supposons que je veuille faire ça? Je prendrai l'adresse comme exemple, le membre a une adresse mais les clubs auront également besoin d'une adresse
Vahx
1
Créez un enregistrement d'adresse et mettez l'ID d'adresse dans le club. Parce qu'un club a 1 adresse, un membre a 1 adresse. Pour les numéros de téléphone, vous devez mettre personId dans l'enregistrement phonenumber pour avoir 1 à plusieurs. ..... Vous pouvez créer une table personPhoneNumber (personId, phonenumberId) + table clubPhoneNumber (clubId, phonenumberId) ce qui en fait alors une relation plusieurs-plusieurs.
aldwinaldwin