Проектирование баз данных SQL Server 2005 года - many-many отношения с иерархией

Примечание:

Я полностью переписал свое исходное сообщение для лучше объяснения проблемы, которую я пытаюсь понять. Я попытался обобщить проблему как можно больше.

Кроме того, моя благодарность исходным людям, которые ответили. Надо надеяться, это сообщение делает вещи немного более ясными.

Контекст

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

Вообразите следующий сценарий для организационной структуры компании:

             Textile Division                    Marketing Division
                    |                                     |
          ----------------------               ----------------------
          |                    |               |                    |
       HR Dept           Finance Dept        HR Dept           Finance Dept
          |                    |               |                    |
      ----------          ----------       ----------           ---------
     |          |         |        |       |        |           |       |
  Payroll     Hiring    Audit     Tax   Payroll   Hiring      Audit  Accounts
     |          |         |        |       |        |           |       |
    Emps      Emps       Emps     Emps    Emps     Emps        Emps    Emps    

NB: Emps обозначает список служащих, которые работают в той области

Когда я сначала запустил с этой проблемы, я сделал четыре отдельных таблицы:

  1. Divisions -> Ткань, Продавая (PK = DivisionID)
  2. Departments -> HR, Финансы (PK = DeptID)
  3. Functions -> Платежная ведомость, Найм, Аудит, Налог, Учетные записи (PK = FunctionID)
  4. Employees -> Список всех Сотрудников (PK = EmployeeID)

Проблема, поскольку я вижу его, состоит в том, что существует несколько many-many отношений, т.е. многие отделы имеют многие подразделения, и много функций имеют многие отделы.

Вопрос

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

  • Получите всех сотрудников, которые работают в функции Платежной ведомости Маркетингового Подразделения

Чтобы сделать это, я должен смочь дифференцироваться между двумя отделами Платежной ведомости, но я не уверен, как это может быть сделано?

Я понимаю, что мог создать таблицу 'Link / Junction' между Отделами и Функциями так, чтобы я мог получить, какие Функции находятся в который Отделы. Однако я должен был бы все еще дифференцировать Подразделение, которому они принадлежат.

Научно-исследовательская работа

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

6
задан Alex P 22 March 2010 в 19:51
поделиться

7 ответов

Основываясь на обновленном сообщении и делая некоторые (довольно очевидные) предположения, основанные на используемых именах, я пришел к следующему.Всего существует четыре объекта:

  • Подразделения
  • Отделы
  • Функции
  • Сущности

Между этими объектами существует множество взаимосвязей. Некоторые из них являются иерархическими, большинство представляют собой простые ассоциации:

  • Вариант A1: есть главный список функций. Каждый отдел может выполнять (или выполнять) одну или несколько функций, и функция может выполняться более чем одним отделом.
  • Вариант A2: Функции «принадлежат» отделам. Никакие функции не могут выполняться двумя или более отделами. (Похоже, так оно и есть, поскольку отдел кадров имеет расчет заработной платы и найма, а финансовый отдел - аудит, налоги и счета.)

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

  • Помимо выполнения работы по функциям, похоже, нет никаких отношений между департаментами и отделами. Между ними нет иерархических отношений, поскольку одно не «владеет» и не содержит другого.

Это приводит к следующим примерно наброскам таблиц:

--  Division  -----
DivisionId  (primary key)

--  Department  ---
DepartmentId  (primary key)

--  Function  -----  (assumes option A2)
FunctionId   (primary key)
DepartmentId (foreign key, references Department)

--  DivisionFunctions  ----
DivisionId  (First column of compound primary key)
FunctionId  (Second column of compound primary key)

(Вы можете дополнительно включить суррогатный ключ для уникальной идентификации каждой строки, но DivisionId + FunctionId будет работать.)

Здесь недостаточно материала для ] полностью описывают, как «сотрудники» вписываются в модель.Учитывая, что сотрудники выполняют работу по функциям: может ли сотрудник выполнять работу более чем одной функции или они выполняют только одну? Выполняет ли сотрудник работу функции независимо от того, для какого подразделения (-ов) она выполняется, или им поручено выполнять работу для одного или нескольких подразделений? Здесь есть два очевидных варианта, хотя возможны и более сложные варианты:

  • Вариант B1: сотрудники выполняют работу одной или нескольких функций внутри отделов и выполняют эту работу для всех отделов, которым требуется эта функция этого отдела.
  • Вариант B2: Сотрудникам назначается выполнение определенной функции в определенном подразделении.

Учитывая это, таблицы могут выглядеть так:

--  Employee  -----  (assumes option B1)
EmployeeId    (primary key)
DepartmentId  (foreign key, references Department)

--  EmployeeFunction  -----  (assumes option B1)
EmployeeId  (First column of compound primary key)
FunctionId  (Second column of compound primary key)

... и, таким образом, все сотрудники, которые могут выполнять функцию, будут выполнять ее для всех подразделений, требующих этого. Или

--  Employee  -----  (assumes option B2)
EmployeeId  (primary key)
DepartmentId  (foreign key, references Department)

--  EmployeeAssignment  -----  (assumes option B2)
EmployeeId  (foreign key, references Employee)
DivisionId  (first of two-column foreign key referencing DivisionFunctions)
FunctionId  (second of two-column foreign key referencing DivisionFunctions)

(Или вместо DivisionId и FunctionId включите необязательный суррогатный ключ из DivisionFunctions.) ... и, таким образом, сотрудники назначаются индивидуально на функции, которые должны выполняться отделом для подразделения.

Но это все еще оставляет много вопросов «что, если / когда»: «принадлежат ли сотрудники» отделам? Могут ли сотрудники входить в несколько отделов (работать в них)? Может, сотрудники относятся к подразделениям? Отслеживаете ли вы, какие функции может выполнять сотрудник, даже если он в настоящее время этим не занимается? Аналогичным образом, отслеживаете ли вы, в каком отделе работает сотрудник, даже если он в настоящее время находится «между функциями»? Если сотрудник может выполнять функции A и B, а подразделению требуются обе эти функции, может ли сотрудник быть назначен для выполнения только функций A, а не B для этого подразделения?

Здесь необходимо провести дополнительное исследование требований, но я ' Хочу думать, что это хорошее начало.

2
ответ дан 17 December 2019 в 04:45
поделиться

Попробуйте дать каждой сущности собственную таблицу, например

//Table Structure
location
    locationId
    name

division
    divisionId
    name
    locationId (fk => location)

department
    deparmentId
    name
    divisionId (fk => division)

function
    functionId
    name
    departmentId(fk => department)

jobrole
    jobroleId
    name
    functionId

course
    courseID
    name

jobrole_course_requirement
    jobroleID
    courseID

employee
     employeeID
     name

employee_jobRole
     employeeID
     jobRoleId

emploeyee_course_attendance
     emploeyee_course_attendanceID
     emploeyeeID
     courseID
     dateAttended

И некоторые примеры селектов

// Get course requirements for an employee
select course.name 
  from course, 
       jobrole_course_requirement, 
       employee_jobRole
  where 
       employee_jobRole.employeeID = 123 and
       jobrole_course_requirement.JobRoleId = employee_jobRole.JobRoleId
       course.courseID = jobrole_course_requirement.courseID
0
ответ дан 17 December 2019 в 04:45
поделиться

Обычно, когда я настраиваю базу данных, я придумываю, какие сущности мне нужны и как они связаны друг с другом (т.е. много-один, один-один, ...). Что вы, похоже, и сделали. Далее я выясняю, что нужно каждой сущности. Например, местоположение может иметь: locationid, адрес, ... Затем, отделы Предполагая, что есть одно местоположение для многих отделов, вы могли бы сделать так, чтобы сущность отдела имела divisionid, locationid, информацию, необходимую каждому отделу. Поэтому, в принципе, если это отношения "один-много", например, одно местоположение для многих подразделений, вы можете просто поместить id местоположения в таблицу подразделений. Однако, если это отношение "многие-ко-многим", то, вероятно, лучше иметь промежуточную таблицу для связи между ними, чтобы не иметь дублирующихся записей с изменением только id.

0
ответ дан 17 December 2019 в 04:45
поделиться

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

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

Вам нужны таблицы для функций, курсов, местоположений, людей, организации и, возможно, некоторые объединяющиеся таблицы, чтобы учесть многие и многие отношения. Но все это не сложно и даже не выходит за рамки базового дизайна. Я рекомендую вам, прежде чем что-либо делать, получить книгу по выбранной вами базе данных и ознакомиться с основами.

1
ответ дан 17 December 2019 в 04:45
поделиться

Вам нужно простое звездное отношение. Должность (таблица фактов) имеет только идентификаторы связанных главных таблиц (Отдел, Подразделение и т.д.). Это позволяет использовать любую комбинацию основных таблиц

Основные таблицы могут иметь простую иерархию, встроенную в каждую из них по мере необходимости. И могут соотноситься друг с другом по мере необходимости. Но детали этого не влияют на запросы к Position

Вы можете сделать ID в Position nullable для необязательных отношений

Вы можете добавить столбцы StartDate и EndDate в Position для отслеживания изменений во времени

Простой пример:

SQL Table Diagram

1
ответ дан 17 December 2019 в 04:45
поделиться

Возможно (возможно) вам следует рассмотреть отдел кадров текстильного отдела как отдельный отдел, нежели отдел кадров отдела маркетинга.

0
ответ дан 17 December 2019 в 04:45
поделиться

Поскольку вы «абекедарианец» :), перед любой попыткой освоить дизайн базы данных нужно прочитать о нормализации и полностью понять все нормальные формы вплоть до 5NF

Если вы хотите чтобы смоделировать это
1. отделы входят в подразделения
2. функции выполняются в отделах
3. сотрудники выполняют функции

и что не все функции выполняются во всех отделах, и не все отделы находятся во всех отделах, то вы должны где-то сохранить этот факт.

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

departments_in_divisions
candidate key: department, division

, затем у вас были некоторые функции в некоторых отделах

functions_departments_divisions
candidate key: function, department, division
references: (department, division) in departments_divisions

, затем у сотрудников были некоторые функции из некоторых отделов и отделов

employees_function_department_division
candidate key: employee, function, department, division
references: (function, department, division) in functions_departments_divisions

После (или до этого) у вас есть еще 3 сущности, функции, отделы и подразделения, которые будут перечислять все возможные отделы, подразделения и функции, на которые также будут ссылаться приведенные выше таблицы (это может быть не полностью нормализовано).

Также имена сущностей (таблиц) могут стать для вас более подходящими (только вы можете знать полную семантику модели ваших данных). Особенно, если вы заметили, что вам нужно присвоить им другие атрибуты (поля).

Значениями для отделов, подразделений и функций являются их названия, в приведенном выше анализе еще нет искусственных идентификаторов. Вы можете представить их на следующем шаге, после логического моделирования, после физического моделирования, или вы можете оставить естественные ключи.Если вы используете искусственные ключи, которые могут сократить использование составных ключей до максимального значения 2, но при этом скрывают связи и значение фактов, которые вы храните в своих таблицах. (Пример functionID может быть и Идентификатор имени функции или идентификатор функции, которая выполняется в определенной комбинации подразделения / отдела - непонятно, что это такое, и они не взаимозаменяемы; вроде как разница между экземпляром и классом).

1
ответ дан 17 December 2019 в 04:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: