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 une société:

  • Entités: Employees,Managers,Departments.
  • Employee ne fonctionne que chez 1 DepartmentDepartment peut avoir de nombreux Employees travailler dessus.
  • Manager peut gérer que 1 Department et même Department peut avoir seulement 1 Manager.
  • Manager supervise de nombreux Employees, mais Employee n'est supervisé par un Manager.

Maintenant, j'ai 2 possibilités pour ce modèle:

première solution:

je considérerai que le Manager entité hérite de la Employee entité considérant que je vais conserver des données qui sont uniques aux gestionnaires (par exemple Bonus & Status).

First Solution

  • puisque la relation entre Department et Employee1:N alors je vais mettre le Department Id clé étrangère dans l' Employee tableau Works relation.

  • puisque la relation entre Department et Manager1:1 alors je vais mettre le Department Id clé étrangère dans l' Manager tableau Manages relation.

problème: comment représenter la relation récursive entre Manager et Employee?


Deuxième solution:

je considérerai que le Manager entité n'est pas nécessaire que d'autres Employees peut aussi avoir un Bonus et Status. (En fait j'ai ajouté ces 2 attributs juste pour voir comment le modéliser dans les deux cas) Second solution

  • puisque la relation entre Department et Employee1:N alors je vais mettre le Department Id clé étrangère dans l' Employee tableau Works relation.
  • puisque la relation entre Employee et Manager1:N alors je vais mettre le Employee Id clé étrangère dans l' Employee tableau Supervises rapport et appelle Manager Id.

problème: comment représenter la relation entre les Manager et <!--4?


Questions:

  1. Est-il des erreurs évidentes dans la conception comme ils sont?
  2. Comment résoudre le problème dans les deux cas?
  3. Est-il mieux la solution de ces deux?
19
demandé sur giannis christofakis 2012-04-01 23:34:14

5 réponses

je dirais probablement quelque chose comme:

enter image description here

Ce modèle présente les caractéristiques suivantes:

  • le directeur "hérite" l'employé.
    • pour représenter un employé, inscrire une seule ligne dans employé.
    • pour représenter un gestionnaire, inscrire une ligne dans employé et une rangée de MANAGER.
  • un ministère peut avoir plusieurs employés.
  • chaque ministère a exactement 1 gestionnaire et chaque gestionnaire gère 0 ou 1 départements.
  • Un superviseur peut être employé ordinaire ou d'un gestionnaire.
  • les ministères ne sont pas tenus de " jumeler":
    • Un superviseur peut travailler dans différents département de l'encadrement de l'employé.
    • un gestionnaire peut gérer un service différent de celui où il travaille.
    • Si un superviseur est responsable, le département (s)il gère, le département (s)il travaille dans et le ministère(s) de ses employés dirigés peuvent tous être différents.

Remarque: Si votre SGBD ne supporte pas les contraintes différées, vous voudrez faire le ministère.MANAGER_ID NULL-able, pour briser le cycle qui vous empêcherait autrement d'insérer les nouvelles données.


si les ministères doivent apparier, alors vous utiliserez une technique propre au SGBD (comme des déclencheurs ou des contraintes "spéciales"), ou "propagerez" DEPARTMENT_ID dans le PK des employés. Cette propagation est ce qui permet finalement l'appariement:

enter image description here

puisque EMPLOYEE_ID doit être globalement unique, il ne peut pas rester dans la clé composite avec le DEPARTMENT_ID. Donc, nous le faisons alternativement clé et à la place d'utiliser la mère porteuse EMPLOYEE_NO dans le PK.

Ce modèle vous empêche d'avoir un gestionnaire qui gère un ministère et travaille dans un autre, ou un superviseur qui supervise les employés à partir d'un autre département.


Dans le cas où vous n'êtes pas familier avec le symbole...

enter image description here

...il dénote une "catégorie". Dans ce contexte, vous pouvez simplement l'interpréter comme une relation "1 à 0 ou 1" entre L'employé et le gestionnaire.

24
répondu Branko Dimitrijevic 2012-04-02 18:22:32

sans entrer dans les détails, je vous assure que la solution employé/Gestionnaire/service est, à long terme, une source de mécontentement (d'abord) puis une véritable PITA (plus tard) pour les personnes en charge de la maintenance de la base de données et/ou du développement de son interface. Je vous conseille donc de vous en tenir à votre deuxième proposition.

en ce qui concerne la relation gestionnaire/ministère, vous avez principalement deux façons de représenter cette relation. Les deux solutions vous autorisent à garder votre récursif "Le Gestionnaire Gère la relation avec L'employé" en plus d'une relation "le gestionnaire gère le ministère" que vous pouvez mettre en œuvre comme suit:

1-first/simple way: ajouter un ID de gestionnaire/employé dans votre table de département. Ce champ est bien sûr une clé étrangère à la table des employés

2 - seconde/solution plus complexe: ajouter une table "manager" avec les champs suivants:

Manager id (PK, surrogate)
Department id (FK)
Employee id (FK)
beginningDate
endingDate

où vous stockerez l'historique de gestion: qui, pour quel département, à partir de quand, jusqu'à lorsque

dans ce cas, n'oubliez pas d'ajouter de la logique (déclencheur, ou contrôle côté client) pour traduire vos règles d'affaires comme vous ne pouvez avoir qu'un seul gestionnaire pour une période spécifique et un ministère spécifique, aucun ministère ne peut rester plus de ... sans gestionnaire, etc.

EDIT:

Position id (PK, surrogate)
Department id (FK)
Employee id (FK)
Position Level (FK)
beginningDate
endingDate

où le "niveau de poste" mène à une autre table qui occupe les différents postes qui peuvent exister dans un ministère, l'un d'entre eux étant évidemment le poste de "gestionnaire".

cette proposition est plus proche de ce qui est utilisé dans la base de données et les logiciels de RH, et vous pourriez ne pas avoir besoin d'une solution aussi complexe. Mais gardez à l'esprit que diviser les êtres humains en plusieurs tables est Toujours une erreur.

EDIT: suite à vos commentaires ...

pour clarifier les choses, je vous conseille d'ajuster vos noms de champ. Je vous propose d'avoir les champs suivants:

Tbl_Employee.id_EmployeeManager

et

Tbl_Department.id_DepartmentManager

en faisant cela, nous (ou n'importe quel développeur) comprendrons immédiatement que id_EmployeeManager participe à la relation récursive entre les personnes, tandis que id_departmanager participe à la relation entre les personnes et ministère.

retournez à vos questions, et selon moi, vous ne devez pas créer le lien suivant:

Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_EmployeeManager

ce faisant, vous voulez dire que quelqu'un ne peut pas être un gestionnaire de département à moins que il gère déjà des employés. Que sur les départements avec un seul employé? Qu'en est-il des personnes nommées gestionnaires d'un ministère nouvellement créé, où aucun employé n'est encore affecté? Il ne fonctionne pas. Le bon lien devrait être:

Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_Employee

vous pouvez bien sûr ajouter quelques règles d'affaires disant par exemple que "un employé qui gère un ministère ne peut être qu'un gestionnaire" (id_Employee existe quelque part comme id_EmployeeManager) ou "un employé qui gère un ministère ne peut pas avoir de gestionnaire (où id_EmployeeManager pour cet employé est null...). Mais ce ne sont que des règles commerciales. 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é!

1
répondu Philippe Grondier 2012-04-03 07:59:24

je pense que c'est la meilleure solution:

DB Design

un gestionnaire est Un employé qui gère un département. La relation récursive, vous pouvez obtenir par le suivant:

L'employé a un ministère Un ministère a un employé comme gestionnaire

peut-être est-il pratique de donner à la table des employés une colonne EmployeeType pour définir le rôle.

0
répondu pascalvgemert 2012-04-01 19:45:13

Mon avis:

personne de Table où vous ajouterez l'information pour les employés et les gestionnaires, les gestionnaires sont des êtres humains aussi, vous savez? :), et vous avez un champ managerId à lier à L'Id du manager.

Table de service avec le ministère de l'information

et, si l'employé peut appartenir à plus d'un ministère, créer une table employee_department pour les relier. Si un employé ne peut appartenir qu'à un seul ministère et que vous n'avez pas besoin de plus d'information la relation, ajouter un champ departmentID sur la table de L'employé.

0
répondu Diego 2012-04-01 20:12:41

pourquoi ne pas s'en tenir à la deuxième conception et avoir une pseudo-relation?

je suppose que vous allez avoir un department_id colonne dans l'entité de L'employé pour lier la relation entre l'employé et les entités du Ministère. Si nous pouvons supposer qu'il n'y aura pas de hiérarchie de MANAGERS (managers of managers) nous pouvons imposer une pseudo-relation entre les deux tables où Department_ID pour les gestionnaires (Manager_ID Null) représente le Ministère qu'ils gèrent.

aussi longtemps que vous documentez cela clairement, je pense que ce serait une approche peu encombrante puisque vous auriez déjà une colonne FK (department_id) dans l'entité de L'employé faisant référence à l'entité du Ministère.

0
répondu Ellest 2017-12-19 20:30:32