Problème de relation d'entité

19

J'ai 4 tableaux liés comme ceci (c'est un exemple):

Company:
ID
Name
CNPJ

Department:
ID
Name
Code
ID_Company 

Classification:
ID
Name
Code
ID_Company

Workers:
Id 
Name
Code
ID_Classification
ID_Department

Supposons que j'aie un classificationavec id = 20, id_company = 1. Et un departmentqui a id_company = 2(qui représente une autre entreprise).

Cela permettra la création d'un travailleur issu de deux entreprises car la classification et le service sont liés à l'entreprise séparément. Je ne veux pas que cela se produise, donc je pense que j'ai un problème avec mes relations et je ne sais pas comment le résoudre.

777Anon
la source
1
Qu'est-ce que la «classification»?
Jehad Keriaki
1
Je suppose que classificationc'est analogue au poste, c.-à-d. Secrétaire, concierge, suzerain, etc.
Erik
Voulez-vous imposer qu'un travailleur doive appartenir au même département que la classification?
Lennart
Peut-être que le département, la classification (et même le travailleur) devraient être considérés comme des entités faibles, toutes dépendant de l'entreprise. Ensuite, la clé Société ferait partie des clés Département, Classification et Ouvrier. Une entité faible est une entité dont l'existence dépend de l'existence d'une autre entité.
miracle173

Réponses:

9

Votre problème provient du fait qu'il manque un type d'entité dans votre modèle. Considérez l'ERD suivant:

ERD

Notez que j'ai ajouté un type d'entité d'intersection entre DEPARTMENTet CLASSIFICATION. Ce nouveau type d'entité: POSITIONfournit les informations implicites dans votre modèle, qu'un département particulier a un ensemble donné de travaux de différentes classifications.

L'ajout POSITIONà votre modèle en tant qu'entité explicite présente quelques avantages.

  1. Cela évite le problème qui vous préoccupe avec une WORKERaffectation potentielle à des départements et des classifications dans différentes entreprises.
  2. Il vous donne un lieu pour d'autres prédicats qui pourraient être applicables à un poste, comme le salaire, etc.
  3. Il vous permet d'enregistrer le fait qu'un poste existe, même s'il n'y a aucun WORKERs actuellement dans le poste, ce qui est très probablement une information utile.

Notez que pour éviter le problème d'un poste défini pour un département et une classification qui sont dans des entreprises différentes, j'ai développé les clés des deux DEPARTMENTet CLASSIFICATION, ce qui est bon pour les raisons que vous pouvez lire longuement dans la réponse de Todd Everett.

ATTENTION Le modèle ci-dessus suppose une simplification. Plus précisément, il suppose que chaque position n'est enregistrée qu'une seule fois. Cela peut ou non être adapté aux règles de votre entreprise. Si vous avez besoin de plusieurs POSITIONenregistrements pour le même service et la même classification au sein d'une entreprise, vous pouvez introduire une clé de substitution POSITION.

Joel Brown
la source
24

Je ne pense pas que vous ayez un problème avec les relations. Je pense plutôt que le problème est qu'en utilisant des clés de substitution (c'est-à-dire des identifiants) pour chaque table, la base de données résultante est incapable d'empêcher les travailleurs d'être insérés dont le département est d'une entreprise tandis que la classification est d'une autre et vice versa. Une bonne façon de comprendre cela est de visualiser le schéma à l'aide d'un outil de création de diagrammes ER. J'utiliserai l' outil Oracle Data Modeler qui est en téléchargement gratuit.

Diagramme ER

entrez la description de l'image ici

Dans l'état actuel des choses, vous pourriez avoir 2 entreprises - dites IBMet Microsoft. IBMpeut avoir un Software Developmentservice et Microsoft peut avoir un Desktop Softwareservice. IBM peut avoir une Software Engineerclassification et Microsoft peut avoir une Software Developerclassification. Maintenant, parce que vous avez une clé de substitution pour Departmentet Classification, le fait qu'il Software Developments'agit d'un IBMdépartement et d' Desktop Softwareun Microsoftdépartement est perdu pour les futures relations avec les enfants. C'est également le cas avec Classification. Par conséquent, il est facile d'affecter accidentellement Harlan Mills, qui est un IBMemployé du Software Developmentdépartement, une classification Software DeveloperdontMicrosoftclassification! De même, le travailleur pourrait recevoir la bonne classification et le mauvais département! Voici un diagramme montrant le premier exemple:

entrez la description de l'image ici

Les 1 Ids représentent IBMet les 2 Ids représentent Microsoft. J'ai mis en surbrillance en rouge le scénario où Harlan Millset Bill Gatessont affectés aux mauvais départements, ce qui est visualisé par l'ID de 10 départements associé à l'ID de classification 200 et vice versa.

Options à résoudre

Alors, quelles sont les options pour empêcher qu'il se produise? Il existe deux options immédiates. La première consiste à réaliser qu'en utilisant une clé de substitution pour chaque table, ce problème existe et à introduire une programmation supplémentaire pour vérifier qu'il ne se produit pas. Cela peut être fait dans l'application, mais si des insertions et des mises à jour peuvent se produire en dehors de l'application, des associations incorrectes peuvent toujours se produire. Une meilleure approche serait de créer un déclencheur qui se déclenche lors de l'insertion et de la mise à jour d'un employé pour s'assurer que le service affecté est de la même société que la classification attribuée, et sinon l'échec de l'insertion ou de la mise à jour.

La deuxième option consiste à ne pas utiliser de clés de substitution pour chaque table. Au lieu de cela, utilisez les clés de substitution uniquement pour la Companytable, qui est fondamentale et n'a pas de parents, puis créez des relations d' identification avec les tables enfant Departmentet Classification. Les tables Departmentet Classificationont maintenant un PK de Company Idplus un numéro de séquence ou un nom pour les distinguer. Ensuite, les relations de Departmentet Classificationà Workerdevenir aussi identifyinget donc le PK de Workerdevient le Company Id, plus le Department Number(j'utilise un numéro de séquence dans cet exemple), plus le Classification Number. Le résultat est qu'il n'y a que one Company Iddans le Workertableau. Il est désormais impossible d'attribuer unWorkerà un Departmentdans un Companyet à un Classificationdans un autre Company.

Pourquoi est-ce impossible? C'est impossible car le schéma implémente l'intégrité référentielle entre Workeret Departmentet Classification. Si une tentative est faite pour insérer un Workerpour un Departmentdans un Companyet un dans un Classificationautre, la combinaison qui n'existe pas dans la table parent correspondante déclenchera une violation d'intégrité référentielle et l'insertion ne fonctionnera pas.

Voici un schéma mis à jour d'une implémentation de la deuxième option: entrez la description de l'image ici

Option privilégiée

Des deux options, je préfère absolument la seconde - en utilisant les relations d'identification et les clés en cascade - pour deux raisons. Tout d'abord, cette option atteint la règle souhaitée sans programmation supplémentaire. Développer un déclencheur n'est pas anodin. Il doit être codé, testé et entretenu. Veiller à ce que la logique de déclenchement soit optimale afin de ne pas affecter les performances n'est pas non plus anodin. Le livre Mathématiques appliquées aux professionnels des bases de données fournit de nombreux détails sur la complexité d'une telle solution. Deuxièmement, les règles impliquent qu'un département et une classification ne peuvent pas exister en dehors du contexte de la Company, et donc le schéma reflète maintenant plus précisément le monde réel.

C'est une excellente question car elle montre exactement pourquoi supposer simplement que chaque table nécessite une clé de substitution est une mauvaise idée. Fabian Pascal a un excellent post blog uniquement sur ce sujet montre que non seulement une clé de substitution peut être une mauvaise idée du point de vue de l' intégrité des données , il peut aussi conduire à rendre des récupérations plus lentesau niveau physique précisément parce que des jointures sont nécessaires qui, si les clés avaient été correctement mises en cascade, seraient inutiles. Un autre sujet intéressant que révèle cette question est qu'une base de données ne peut pas garantir que toutes les données qui y sont insérées sont exactes par rapport au monde réel. Au lieu de cela, il ne peut que garantir que les données qui y sont insérées sont cohérentes avec les règles qui lui sont déclarées. Dans ce cas, nous pouvons faire de notre mieux en utilisant l'approche par clé en cascade pour nous assurer que le SGBD peut garder les données cohérentes par rapport à la règle selon laquelle un Workerd'un donné Companydoit être affecté d'un Classificationet un Departmentde ce même Company. Mais, si dans le monde réel Microsofta un département appelé Desktop Softwaremais l'utilisateur de la base de données affirme que le département est à la placeSoftware Development le SGBD ne peut rien faire d'autre que supposer qu'il a reçu un fait réel.

Todd Everett
la source
1

D'après ce que je comprends de la question, le champ ID_Classification de la table 'Workers' ne devrait autoriser que les classifications définies pour l'entreprise du travailleur respectif. Par conséquent, la validation (en attachant une règle ou via des déclencheurs) des informations insérées / mises à jour dans le champ Workers.ID_Classification est suffisante pour répondre à cette exigence.

Haris
la source
1

D'après mes lectures, je ne comprends toujours pas ce qu'est cette classification et pourquoi doit-elle avoir l' ID_Company . Si c'est comme une position comme quelqu'un l'a mentionné ici, je pense qu'une table statique pour contenir toutes les positions serait mieux.

Si vous faites cela afin de trouver facilement une classification / position dans une entreprise, veuillez ajouter une simple requête / vue pour connecter les services -classification-travailleurs et récupérer l'ID de la société de la classification.

de nos jours, il existe des vues ou des technologies plus intelligentes telles que les vues matérialisées et les index de jointure, donc si votre problème concerne les performances de la requête, utilisez-les.

Johns
la source