11
votes

Comment modéliser une base de données avec de nombreuses relations m: n sur une table

Je suis en train de créer une base de données qui possède un grand nombre de relations nombreuses à plusieurs. Chaque relation a été modélisée via une table de liaison. Exemple:

Une personne possède un certain nombre d'emplois, un certain nombre de personnes sont remplies par un certain nombre de personnes. Une personne possède un certain nombre de maisons, des maisons sont occupées par un certain nombre de personnes. Une personne a un certain nombre de restaurants qu'il aime, les restaurants ont un certain nombre de personnes qui aiment le restaurant.

Je suis d'abord conçu cela comme suit:

Tables: Personne, Job, Maison, Restaurant, Person_job, Person_House, Person_Restaurant.

Relations 1 - N: Personne -> Person_job, personne -> Person_house, personne -> Person_Restaurant, Job -> Person_Job, Maison -> Person_House, Restaurant -> Person_Restaurant.

Cela conduit assez rapidement à un modèle ER surpeuplé et complexe.

essayer de simplifier cela, je l'ai modelé comme suit:

Tabels: Personne, Job, Maison, Restaurant, Person_attributes

Relations 1 - N: Personne -> Person_attributes, Job -> Person_attributes, Maison -> Person_attributes, Restaurant -> Person_attributes

La table Person_Attributes doit ressembler à ceci comme suit: personnal jobidiste filet Restauragid

Si une personne - relation de travail existe, je vais ajouter une entrée ressemblant à:

P1, J1, NULL, NULL

Si une relation de maison existe, je vais ajouter une entrée ressemblant à:

P1, NULL, H1, NULL

La table des attributs dans le deuxième exemple aura le même nombre d'entrées que les tables de liaison des premiers exemples ajoutés.

Ceci simplifie beaucoup le modèle ER, et tant que je construise des index pour PersonID + Jobidid, PersonID + MEILLIID et PERSONID + RESTAURID, il n'y aura pas beaucoup d'impact sur la performance, je pense.

Mes questions sont: La deuxième méthode est-elle une méthode correcte de la modélisation? Sinon, pourquoi? Est-ce que j'ai raison sur l'impact de la performance? Sinon, pourquoi?

MySQL Workbench Exemple de ce que je veux dire peut être trouvé ici:

http://www.2shared.com/file/3GBNODEZ/example.html < / a>


1 commentaires

Votre première méthode est correcte. Il n'y a rien de mal avec ce modèle ER.


5 Réponses :


1
votes

À mon humble avis, j'irais pour le premier modèle. C'est probablement un modèle plus complexe mais à la fin, cela facilitera les choses lorsque vous extrayez des informations des tables et que le code d'application pourrait devenir plus sale ou plus illisible pour les autres programmeurs. À côté, il y a des auteurs qui ne recommandaient pas d'utiliser des tables polyvalentes comme celle-là.

À la fin, vous devez aller avec tout ce qui vous convient mieux. Nous ne savons pas que tout le contexte ne peut donc pas vous aider trop à décider. Mais pour ce que vous dites et je vais certainement aller pour l'option numéro un.


1 commentaires

La situation du monde réel pour cet exemple est (bien sûr) plus complexe. Je ne pense pas que cela soit plus complexe pour un programmeur. Se référant à personne_attributes. houseID est probablement encore plus significatif que PERSON_HOUSI. HOUSEID. Se demandant toujours si et comment cela va avoir une incidence sur la performance.



2
votes

Votre version simplifiée ne représente pas un modèle relationnel approprié. C'est plus d'un modèle de métadonnées.

Le nombre de tables de votre base de données doit représenter le nombre d'entités logiques de votre domaine. Cela ne devrait pas changer en fonction de certaines idées arbitraires du nombre d'entités trop nombreuses.


3 commentaires

Alors pourquoi n'est-ce pas un modèle approprié? Je conviens que l'idée de «trop d'» est l'arbitrat, mais de garder le modèle aussi simple que possible et lisible (et compréhensible) le plus possible.


Ce n'est pas un modèle approprié car il ne reflète pas avec précision la situation que vous essayez de modéliser, pour les différentes raisons décrites par les quatre réponses parfaitement correctes que vous avez.


Comme le dit Tomfanning, consultez d'autres réponses beaucoup plus complètes. Je voulais ajouter que votre modèle d'origine est beaucoup plus compréhensible que votre version simplifiée. Toute personne qui comprend la conception relationnelle comprendrait (et être capable d'interroger) votre modèle d'origine en quelques minutes.



2
votes

Je ne pense pas que la deuxième méthode est correcte car votre table_atributes contiendrait des données redondantes. Par exemple: Disons qu'une personne aime 10 restaurants et travaille sur 2 emplois, dispose de 3 maisons que vous auriez autant que 10 * 2 * 3 entrées où il devrait être 10 + 2 + 3 (dans 3 tables de liaison ... selon l'approche n ° 1) . Pensez aux inconvénients ayant un million d'utilisateurs et si vous aviez plus de 3 attributs dans la table Person_Attributes pour gérer ... Donc, j'irais avec une approche 1 dans votre question.

dire par exemple votre table_attributes a suivi l'entrée: xxx

maintenant si la personne aime les restaurants R2 et R3 .. .table ressemble à xxx

table a déjà des données redondantes Il ajoute le travail J2 à un moment ultérieur .. Votre table ressemblera à xxx

considérez maintenant qu'il ajoute une autre maison H2 .. donc sur et ainsi de suite, voyez-vous mon point? >


4 commentaires

Désolé mais vous auriez encore 15 entrées dans la deuxième situation, cela ne change pas.


15 entrées représentant 15 faits. Je ne sais pas comment vous pourriez modeler cela mieux que votre première solution.


Oui, je vois ton point, mais ce n'est pas comme ça que j'essaie de modéliser. La table des attributs va être p1, h1, null, null; P2, h1, null, null; P1, NULL, J1, NULL, ETC ...


Votre exemple a des données incohérentes: 1 enregistrement pour P1 a la saisie H1 pour la maison et le 2e dossier a «NULL» pour la maison. Si je requête par personne = p1 Que choisirais-je d'être correct de la valeur à la maison pour la personne P1 'NULL' ou "H1"? Il serait assez complexe et inefficace d'écrire un code qui utilise SQL Result Renvoyé. Si, cependant, nous l'avons écrit, le problème reste-t-il toujours la même relation entre 3 entités: Si les nouvelles entrées J2 R1 et R2 sont liées à P1..Art à ajouter ... Comment l'ajoutez-vous à votre table qui a Entrées: {P1, H1, 'NULL,' NULL} et {P1, 'NULL, J1,' NULL} Comment choisiriez-vous ces entrées?



21
votes

Votre conception viole quatrième formulaire normal . Vous essayez de stocker plusieurs "faits" dans une table et cela conduit à des anomalies.

La table Person_Attributes devrait ressembler à ceci comme suit: Personid Jobid Houseid Restauragidid P> blockQuote>

Donc, si je m'associe à un emploi, une maison, mais deux restaurants, puis-je stocker ce qui suit? p> xxx pré>

et si j'ajoute un troisième restaurant , Je copier em> les autres colonnes? P> xxx pré>

fait! Oh, attends, que s'est passé là-bas? J'ai changé d'emploi en même temps que l'ajout du nouveau restaurant. Maintenant, je suis mal associé à deux travaux, mais il n'ya aucun moyen de distinguer les correctement em> associé à deux travaux. P>

aussi, même s'il est correct d'être associé Avec deux travaux, les données ne devraient-elles pas ressembler à ceci? P>

personId jobId houseId restaurantId
    1234   123      87         5678
    1234    42    NULL         9876


1 commentaires

N'oubliez pas que votre application peut créer une table .



1
votes

Le deuxième modèle est un problème de plusieurs perspectives. Tout d'abord, il est susceptible de créer des problèmes de blocage car tout se passe sur une table de méta. Deuxièmement, il est beaucoup plus susceptible d'avoir des problèmes d'intégrité des données car vous ne pouvez pas appliquer les contraintes de clé étrangère. C'est un anticipateur SQL pour modéliser de cette façon. Le premier modèle était correct.


0 commentaires