2012-04-01 4 views
18

Рассмотрим случай, когда я пытаюсь моделировать базу данных для компании:Проектирование базы данных для рекурсивного отношения

  • Entities: Employees, Managers, Departments.
  • Employee работает только в 1 Department, а Department может иметь много Employees, работающих в нем.
  • A Manager может управлять только 1 Department и аналогичным образом Department может иметь только 1 Manager.
  • A Manager контролирует многие Employees, но Employee контролирует только один Manager.

Теперь у меня есть 2 способа модели это:

Первое решение:

Я считаю, что Manager объект наследует от Employee объекта, учитывая, что я буду сохраняйте данные, которые уникальны для Менеджеров (например, Бонус & Статус).

First Solution

  • Поскольку соотношение между Department и Employee является 1:N тогда я положу Department Id в качестве внешнего ключа в таблице Employee для Works отношения.

  • Поскольку соотношение между Department и Manager является 1:1 тогда я положу Department Id в качестве внешнего ключа в таблице Manager для Manages отношения.

Проблема: Как я могу представить рекуррентное соотношение между Manager и Employee?


Второе решение:

Я считаю, что Manager объект не нужен, поскольку другой Employees может также иметь Bonus и Status.(На самом деле я добавил эти 2 атрибуты, чтобы посмотреть, как смоделировать его в обоих случаях) Second solution

  • Поскольку соотношение между Department и Employee является 1:N тогда я положу Department Id в качестве внешнего ключа в Employee таблица для Works отношение.
  • Поскольку соотношение между Employee и Manager является 1:N тогда я положу Employee Id в качестве внешнего ключа в таблице Employee для Supervises связи и называют его Manager Id.

Проблема: Как я могу представить отношение между Manager и Department?


Вопросы:

  1. Есть ли какие-либо очевидные ошибки в области дизайна, как они?
  2. Как решить каждую проблему в обоих случаях?
  3. Есть ли лучшее решение, чем эти два?

ответ

23

Я бы, вероятно, пойти что-то вроде:

enter image description here

Эта модель имеет следующие характеристики:

  • менеджер "наследует" сотрудник.
    • Чтобы представить сотрудника, вставьте одну строку в EMPLOYEE.
    • Чтобы представить менеджера, вставьте одну строку в EMPLOYEE и одну строку в MANAGER.
  • Отдел может иметь несколько сотрудников.
  • Каждый отдел имеет ровно 1 менеджера, и каждый менеджер управляет 0 или 1 отделами.
  • Наблюдателем может быть обычный сотрудник или менеджер.
  • Департаменты не обязаны «соответствовать»:
    • Супервизор может работать в другом отделении от подконтрольного работника.
    • Менеджер может управлять различным отделом, откуда он работает.
    • Если руководитель является менеджером, то отделы, которыми он управляет, отделы, в которых он работает, и отдел (ы) его/ее контролируемых сотрудников могут быть разными.

ПРИМЕЧАНИЕ: Если СУБД не поддерживает отложенные ограничения, вы хотите сделать DEPARTMENT.MANAGER_ID NULL-возможность, чтобы разорвать порочный круг, который в противном случае предотвратить бы вам вставлять новые данные.


Если отделы должны соответствовать, то вы либо использовать технику СУБД специфические (например, триггеры или «специальных» ограничений), или «распространяться» на department_id в ПК сотрудников. Это распространение является то, что в конечном счете позволяет сращивание:

enter image description here

Поскольку EMPLOYEE_ID должно быть глобально уникальным, он не может оставаться в композиционном ключе вместе с DEPARTMENT_ID. Итак, мы делаем его альтернативным ключом и вместо этого используем суррогатный EMPLOYEE_NO в ПК.

Эта модель запрещает вам иметь менеджера, который управляет одним отделом и работает в другом, или супервизор, который контролирует сотрудников из другого отдела.


В случае, если вы не знакомы с символом ...

enter image description here

... это означает "категорию". В этом контексте вы можете просто интерпретировать его как отношение «1 к 0 или 1» между EMPLOYEE и MANAGER.

+0

+1 для усилий с диаграммами – Bohemian

+0

+1 для иллюстративного ответа :) Но вы уверены, что эта часть правильная? «Поскольку EMPLOYEE_NO должен быть глобально уникальным, он не может оставаться в составном ключе вместе с DEPARTMENT_ID» _? Возможно, вы имели в виду 'EMPLOYEE_ID'? и что именно вы подразумеваете под _ «Если отделы должны соответствовать« _? – Songo

+0

@ Сонго Я сделал опечатку (это должен быть ID не НЕТ), исправлено, спасибо! –

0

Мое мнение:

Таблица Person, где вы будете добавлять информацию для сотрудников и руководителей, менеджеры тоже человек, вы знаете? :), и у вас есть поле managerId для ссылки на Id менеджера.

Таблица отдела информации отдела

и, если работник может принадлежать более, что один отдел, создать таблицу EMPLOYEE_DEPARTMENT соотносить их. Если сотрудник может принадлежать только одному отделу, и вам не нужна дополнительная информация в отношении, добавьте поле departmentID в таблицу Employee.

+0

Один стол, чтобы держать их всех, как мое второе решение? Вы в основном предлагаете, чтобы таблица Employee имела следующую структуру: «Сотрудник (идентификатор сотрудника, имя сотрудника, идентификатор менеджера, идентификатор отдела, идентификатор отдела отдела)», правильно? – Songo

+0

вам не нужен идентификатор отдела отдела, только идентификатор отдела, потому что если сотрудник является менеджером, его отдел будет храниться в столбце departmentId – Diego

+0

Но «менеджер» отдела «не может быть« менеджером » «Сотрудник». «Менеджер» для «Сотрудника» - это его непосредственный руководитель, а не весь менеджер отдела. Как это решить? – Songo

0

Я думаю, что это лучшее решение:

DB Design

менеджер является сотрудником, который управляет отделом. Рекурсивное отношение вы можете получить следующий поток:

Сотрудника имеет отдел Отдел имеет сотрудник в качестве менеджера

Может быть, его удобно, чтобы дать таблице служащего столбец EmployeeType для определения роли.

+0

«Диспетчер» 'Департамента', возможно, не является« Менеджером »« Сотрудника ». «Менеджер» для «Сотрудника» - это его непосредственный руководитель, а не весь менеджер отдела. Как это решить? – Songo

+0

Если я это хорошо понимаю, то, полагаю, давая Работнику отношение к сотруднику, который является менеджером. Таким образом, таблица employee получает поле ManagerID, относящееся к EmployeeID. – pascalvgemert

1

Не вдаваясь в подробности, я заверяю вас, что решение Employee/Manager/Department в долгосрочной перспективе является источником неудовольствия (сначала), а затем реальной PITA (позже) для лиц, ответственных за поддерживая базу данных и/или разрабатывая ее интерфейс. Поэтому я рекомендую вам придерживаться вашего второго предложения.

Что касается отношения между менеджером и департаментом, у вас есть в основном два способа представления этого отношения.Оба решения разрешают вам поддерживать рекурсивное отношение «Менеджер управляет сотрудником» в дополнение к соотношению «управляющий менеджером», которое вы можете реализовать следующим образом:

1 - первый/простой способ: добавить идентификатор менеджера/сотрудника в свой таблица отделов. Это поле, конечно, внешний ключ к таблице сотрудников

2 - второй/более сложное решение: добавить «менеджер» таблицу со следующими полями:

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

, где вы будете хранить историю управления: кто, для какого отдела, от когда, до когда

В этом случае не забудьте добавить некоторую логику (триггер или управление на стороне клиента), чтобы перевести ваши бизнес-правила, например, у вас может быть только один менеджер для определенного период и конкретный отдел, ни один отдел не может оставаться более ... без менеджера и т. д.

EDIT:

3 - богаче решение было бы обобщением моего второго предложения, и позволит вам следить за карьерой каждого в компании. Вы можете сделать это с «работает в» таблице, например, этот (как мы его называем здесь «позиции» таблицу, я буду держать ту же терминологию здесь:

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

Где уровень позиции 'приводит к

Это предложение ближе к тому, что используется в кадровой базе данных и программном обеспечении, и вам может не понадобиться такая информация, которая может быть использована в отделе, одна из которых, конечно, является «менеджером». комплексное решение, но имейте в виду, что расщепление людей в нескольких таблицах ВСЕГДА является ошибкой.

EDIT: после вашего комментария ...

Чтобы все было ясно, я бы посоветовал вам изменить названия полей. Я предлагаю вам иметь следующие поля:

Tbl_Employee.id_EmployeeManager 

и

Tbl_Department.id_DepartmentManager 

Делая это, мы (или любой developper) сразу поймет, что id_EmployeeManager участвует в рекурсивной связи между людьми, в то время как id_DepartmentManager участвует в отношениях между людьми и отделом.

Вернуться на ваши вопросы, и по мне, вы не должны создать следующую ссылку:

Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_EmployeeManager 

Поступая таким образом, вы это означает, что кто-то не может быть менеджером отдела если он не является уже управляющих сотрудниками. Как насчет отделов с одним сотрудником? Как насчет людей, названных менеджерами недавно созданного отдела, где еще не выделен сотрудник? Это не работает. Правая ссылка должна быть:

Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_Employee 

Конечно, вы можете добавить некоторые бизнес-правила, говоря, например, что «сотрудник управления отделом может быть только менеджером» (id_Employee существует где-то, как id_EmployeeManager) или «сотрудник управление у отдела нет менеджера (где id_EmployeeManager для этого сотрудника имеет значение null ...).Но это только бизнес-правила. Ваша модель данных чиста, чтобы принимать все правила до тех пор, пока соблюдается основное правило, а именно то, что отдел управляется сотрудником!

+0

+1 за отличное объяснение :) Но у меня мало вопросов. В своем первом (и самом простом) решении вы сказали, что я должен добавить поле Id Manager/Employee Id в таблицу отдела. Поскольку я уже добавил «Диспетчер менеджера» в таблицу «Сотрудник» для рекурсивного отношения, я должен добавить «Диспетчер менеджера» в таблицу «Департамент», ссылаясь на «Идентификатор менеджера» в таблице «Сотрудник»? Таким образом, только менеджер может управлять отделом, а не сотрудником, которого я считаю. – Songo

0

Как насчет того, чтобы придерживаться 2-й конструкции и иметь псевдосвязь?

Я предполагаю, что у вас будет столбец department_id в сущности Employee, чтобы связать отношения между Employee и подразделениями. Если мы можем предположить, что иерархии менеджеров не будет (менеджеров менеджеров), мы можем обеспечить псевдосвязь между двумя таблицами, где Department_ID для менеджеров (Manager_ID - Null) представляет собой Отдел, которым они управляют.

До тех пор, пока вы четко документируете это, я думаю, что это будет подход, основанный на использовании пространства, поскольку у вас уже будет столбец FK (department_id) в сущности Employee, ссылающейся на объект отдела.

Смежные вопросы