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 classification
avec id = 20, id_company = 1
. Et un department
qui 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.
database-design
constraint
777Anon
la source
la source
classification
c'est analogue au poste, c.-à-d. Secrétaire, concierge, suzerain, etc.Réponses:
Votre problème provient du fait qu'il manque un type d'entité dans votre modèle. Considérez l'ERD suivant:
Notez que j'ai ajouté un type d'entité d'intersection entre
DEPARTMENT
etCLASSIFICATION
. Ce nouveau type d'entité:POSITION
fournit 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.WORKER
affectation potentielle à des départements et des classifications dans différentes entreprises.WORKER
s 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
DEPARTMENT
etCLASSIFICATION
, 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
POSITION
enregistrements pour le même service et la même classification au sein d'une entreprise, vous pouvez introduire une clé de substitutionPOSITION
.la source
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
Dans l'état actuel des choses, vous pourriez avoir 2 entreprises - dites
IBM
etMicrosoft
.IBM
peut avoir unSoftware Development
service et Microsoft peut avoir unDesktop Software
service. IBM peut avoir uneSoftware Engineer
classification et Microsoft peut avoir uneSoftware Developer
classification. Maintenant, parce que vous avez une clé de substitution pourDepartment
etClassification
, le fait qu'ilSoftware Development
s'agit d'unIBM
département et d'Desktop Software
unMicrosoft
département est perdu pour les futures relations avec les enfants. C'est également le cas avecClassification
. Par conséquent, il est facile d'affecter accidentellementHarlan Mills
, qui est unIBM
employé duSoftware Development
département, une classificationSoftware Developer
dontMicrosoft
classification! De même, le travailleur pourrait recevoir la bonne classification et le mauvais département! Voici un diagramme montrant le premier exemple:Les 1 Ids représentent
IBM
et les 2 Ids représententMicrosoft
. J'ai mis en surbrillance en rouge le scénario oùHarlan Mills
etBill Gates
sont 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
Company
table, qui est fondamentale et n'a pas de parents, puis créez des relations d' identification avec les tables enfantDepartment
etClassification
. Les tablesDepartment
etClassification
ont maintenant un PK deCompany Id
plus un numéro de séquence ou un nom pour les distinguer. Ensuite, les relations deDepartment
etClassification
àWorker
devenir aussiidentifying
et donc le PK deWorker
devient leCompany Id
, plus leDepartment Number
(j'utilise un numéro de séquence dans cet exemple), plus leClassification Number
. Le résultat est qu'il n'y a queone
Company Id
dans leWorker
tableau. Il est désormais impossible d'attribuer unWorker
à unDepartment
dans unCompany
et à unClassification
dans un autreCompany
.Pourquoi est-ce impossible? C'est impossible car le schéma implémente l'intégrité référentielle entre
Worker
etDepartment
etClassification
. Si une tentative est faite pour insérer unWorker
pour unDepartment
dans unCompany
et un dans unClassification
autre, 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:
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
Worker
d'un donnéCompany
doit être affecté d'unClassification
et unDepartment
de ce mêmeCompany
. Mais, si dans le monde réelMicrosoft
a un département appeléDesktop Software
mais 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.la source
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.
la source
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.
la source