Conception de base de données pour une relation récursive
Voici un cas où je suis en train de modéliser une base de données pour l'entreprise: les
- Entités:
Employees
,Managers
,Departments
. - Un
Employee
travaille à seulement 1Department
tout unDepartment
peut avoir de nombreusesEmployees
travail. - Un
Manager
peut gérer uniquement 1Department
et de mêmeDepartment
peuvent avoir seulement 1Manager
. - Un
Manager
supervise de nombreuxEmployees
, mais unEmployee
n'est supervisé par unManager
.
Maintenant, j'ai 2 possibilités pour ce modèle:
Première solution:
Je vais considérer que le Manager
entité hérite de la Employee
entité considérant que je vais garder de données qui est unique pour les Gestionnaires (par exemple, primes & Mode).
-
Étant donné que la relation entre
Department
etEmployee
est1:N
alors je vais mettre le
Department Id
de clé étrangère dans laEmployee
table pour leWorks
relation. -
Étant donné que la relation entre
Department
etManager
est1:1
alors je vais mettre le
Department Id
de clé étrangère dans laManager
table pour leManages
relation.
Problème: Comment puis-je représenter la relation récursive entre les Manager
et Employee
?
Deuxième solution:
Je vais considérer que le Manager
entité n'est pas nécessaire que d'autres Employees
peut également avoir un Bonus
et Status
. (En fait, j'ai ajouté ces 2 attributs, juste pour voir comment le modèle dans les deux cas)
- Étant donné que la relation entre
Department
etEmployee
est1:N
alors je vais mettre le
Department Id
de clé étrangère dans laEmployee
table pour leWorks
relation. - Étant donné que la relation entre
Employee
etManager
est1:N
alors je vais mettre le
Employee Id
de clé étrangère dans laEmployee
table pour leSupervises
relation et de l'appelerManager Id
.
Problème: Comment peut-on se représenter la relation entre la Manager
et Department
?
Questions:
- Est-il des erreurs évidentes dans la conception comme ils sont?
- Comment résoudre le problème dans les deux cas?
- Est-il une meilleure solution que ces deux?
Vous devez vous connecter pour publier un commentaire.
Je serais probablement aller avec quelque chose comme:
Ce modèle a les caractéristiques suivantes:
REMARQUE: Si votre SGBD ne prend pas en charge différée contraintes, vous aurez envie de faire le MINISTÈRE.MANAGER_ID NULL-mesure, de briser le cycle qui empêcherait vous d'insérer les nouvelles données.
Si les ministères sont tenus de match, vous devez alors utiliser un SGBD-technique spécifique (comme les déclencheurs ou "spécial" contraintes), ou de "propager" la DEPARTMENT_ID dans le PK des employés. Cette propagation est ce qui permet la mise en correspondance:
Depuis EMPLOYEE_ID doit être unique au monde, il ne peut pas rester dans le composite clé avec le DEPARTMENT_ID. Donc, nous faisons une autre clé et d'utiliser plutôt la substitution EMPLOYEE_NO dans le PK.
Ce modèle ne vous empêche d'avoir un gestionnaire qui gère un département et travaille dans une autre, ou d'un superviseur, qui supervise les employés d'un département différent.
Dans le cas où vous n'êtes pas familier avec le symbole...
...il dénote une "catégorie". Dans ce contexte, vous pouvez simplement l'interpréter comme un "1 à 0 ou 1" relation entre l'EMPLOYÉ et le GESTIONNAIRE.
EMPLOYEE_ID
peut-être ? et que voulez-vous dire par "Si les ministères sont tenus de match" ?DEPARTMENT_ID
dans leDEPARTMENT
table à la foisPK
&FK
? Si c'est unFK
c'est quoi le référencement?DEPARTMENT {DEPARTMENT_ID, MANAGER_NO}
référencementMANAGER {DEPARTMENT_ID, MANAGER_NO}
.MANAGER.DEPARTMENT_ID
(pasDEPARTMENT_NO
).Department
premier, mais depuisDEPARTMENT_ID
référence à laMANAGER
table, puis je vais devoir ajouter unManager
premier, mais depuis leManager Id
référence à laEMPLOYEE
table, alors je doit créer unEmployee
d'abord, mais aussi de créer unEmployee
je dois attribuer une valeur pour sonDEPARTMENT_ID
qui fait référence à laDEPARTMENT
table... et je suis de retour à la case départ, une sensation de vertige :SDEPARTMENT.MANAGER_ID
(comme déjà mentionné dans ma réponse). Permettant la valeur NULL est probablement pas une option dans le deuxième diagramme, puisque la partie de la FK de l'enfant du point de terminaison est en PK. Si vous voulez vraiment de la deuxième diagramme et vous utilisez SGBD sans le soutien de report de contraintes, vous aurez probablement être forcé à utiliser une base de données de mécanisme spécifique comme des déclencheurs pour faire respecter l'intégrité.Sans entrer dans les détails, je ne peux vous assurer que l'Employé/Manager/Département de la solution, sur le long terme, une source de mécontentement (au début) puis un vrai pain PITA (plus tard) pour les personnes en charge de l'entretien de la base de données et/ou développer son interface. Donc, je ne vous conseille de vous en tenir à votre 2ème proposition.
Concernant le gestionnaire ou le service concernant, vous avez essentiellement deux façons de représenter cette relation. Deux solutions vous autorise à garder votre récursive "Manager gère Employé" relation en plus d'un "manager gère Département" que vous pouvez mettre en œuvre comme suit:
1 - première/moyen simple: ajouter un manager/id de l'employé au sein de votre service de table. Ce champ est bien sûr une clé étrangère vers la table des employés
2 - seconde/plus complexes solution: ajouter un "gestionnaire" de la table avec les champs suivants:
où vous allez stocker l'historique de la gestion: qui, pour lequel le département, à partir de quand, jusqu'à quand
Dans ce cas, ne pas oublier d'ajouter un peu de logique (le déclencheur ou le contrôle côté client) pour traduire vos règles d'entreprise comme vous ne pouvez avoir qu'un seul gestionnaire pour une période spécifique et d'un service spécifique, aucun ministère ne peut rester plus de ... sans gestionnaire, etc.
EDIT:
3 - une solution plus riche serait une généralisation de ma deuxième proposition, et vous permettra de garder une trace de carrière dans l'entreprise. Vous pouvez le faire avec une "fonctionne dans le" tableau, comme celui-ci (comme on l'appelle ici une "position" de la table, je vais garder la même terminologie ici:
Où "le niveau de la position" conduit à une autre table contenant les différentes positions qui peuvent exister dans un département, l'un d'entre eux étant bien sûr le "manager" de position.
Cette proposition est plus proche de ce qui est utilisé dans les RH de la base de données et des logiciels, et vous ne pourriez pas besoin d'une telle solution complexe. Mais gardez à l'esprit que la division des êtres humains en plusieurs tables est TOUJOURS une erreur.
EDIT: suite à vos commentaires ...
À mettre les choses au clair, je vous conseille de régler vos noms de domaine. J'aimerais vous proposer d'avoir les champs suivants:
et
Ce faire, nous (ou tout développeur) sera immédiatement comprendre que id_EmployeeManager participe à la relation récursive entre les personnes, tout en id_DepartmentManager participe à la relation entre les gens et le service.
Retour à vos questions, et selon moi, il ne faut pas créer le lien suivant:
Ce faisant, vous êtes ce qui signifie que quelqu'un ne peut pas être un chef de service sauf il est déjà la gestion des employés. Que sur les départements avec un seul employé? Ce qui concerne les gens nommés responsables d'un département nouvellement créé, où encore aucun employé n'est-il attribué? Il ne fonctionne pas. Le lien devrait être:
Vous pouvez bien sûr ajouter certaines règles de gestion en disant par exemple que "l'employé de la gestion d'un département ne peut être qu'un manager" (id_Employee existe quelque part que id_EmployeeManager) ou "un employé de la gestion d'un département ne peut pas avoir un manager (où id_EmployeeManager pour cet employé est nul...). Mais ce ne sont que des règles d'affaires. Votre modèle de données est propre à accepter toutes les règles, tant que la règle de base est respecté, qui est qu'un département est géré par un employé!
Manager Id
àEmployee
table pour le récursive relation alors que je devrais ajouter unManager Id
à laDepartment
tableau référençant lesManager Id
dans leEmployee
de la table de droite ? De cette façon, seul un manager peut gérer un service pas un employé, je pense.Je pense que c'est la meilleure solution:
Un gestionnaire est un employé qui gère un département.
La relation récursive, vous pouvez obtenir par le prochain flux:
Employé dispose d'un département
Un département a un employé à titre de gestionnaire
Peut-être pratique pour donner à l'employé une table EmployeeType colonne pour définir le rôle.
Manager
d'unDepartment
peut-être pas leManager
de laEmployee
. LeManager
pour laEmployee
est son supérieur hiérarchique direct pas l'ensemble de la chef de service. Comment résoudre ce problème?Mon avis:
Table Personne où vous allez ajouter de l'info pour les employés et les gestionnaires, les gestionnaires être humain aussi, vous savez? :), et vous avez un managerId domaine de liaison à l'Id de la gestionnaire.
Table de service avec le ministère de l'information
et, si l'employé peut appartenir à plus qu'un seul ministère, créer une table employee_department de les raconter. Si un employé peut appartenir qu'à un seul département et vous n'avez pas besoin de plus d'info dans la relation, ajouter un departmentID champ de la table Employee.
Employee (Employee Id, Employee Name, Manager Id, Department Id, Manager Department Id)
droit?Manager
d'unDepartment
peut-être pas leManager
de laEmployee
. LeManager
pour laEmployee
est son supérieur hiérarchique direct pas l'ensemble de la chef de service. Comment résoudre ce problème?Manager
s'étendEmployee
) comment puis-je faire une relation récursive entre eux? Ajouter unManager Id
colonne de la table de baseEmployee
peut-être?Comment coller avec le 2ème de conception et d'avoir une pseudo-relation?
Je suis en supposant que vous allez avoir un
department_id
colonne de l'Employé de l'entité de liaison de la relation entre l'Employé et le Ministère des entités. Si on peut supposer qu'il n'y a pas de hiérarchie du gestionnaire (gestionnaires de gestionnaires), nous pouvons appliquer une pseudo-relation entre les deux tables oùDepartment_ID
pour les gestionnaires (Manager_ID
est Null) représente le Ministère qu'ils gèrent.Aussi longtemps que vous le document clairement, je pense qu'il serait un espace-efficace de l'approche que vous aurait déjà un FK colonne (
department_id
) à l'Employé de l'entité de référence le Ministère de l'entité.