Лучшие практики для хранения данных дерева в базе данных - PullRequest
3 голосов
/ 01 ноября 2011

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

Так как вы храните данные? Решение 1. Казалось бы, у таблицы employee может быть manager_id или у вас может быть таблица employee_manager (таким образом, у вас может быть много или ноль менеджеров).

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

Так что вы все думаете?

Ответы [ 4 ]

4 голосов
/ 01 ноября 2011

Я согласен с другими .. Доступна рекурсия.

Я бы не поместил manager_id в таблицу emp (несмотря на древнюю мудрость Скотта / Тигра).Реальный мир все время нарушает это бизнес-правило, и оно не очень хорошо нормализовано.

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

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

3 голосов
/ 01 ноября 2011

Самые популярные базы данных SQL do поддерживают рекурсивные запросы.

  • Большинство баз данных поддерживают рекурсивные CTE .
  • Oracle также поддерживает CONNECT BY .
  • MySQL, к сожалению, тоже не поддерживает.
2 голосов
/ 01 ноября 2011

Вы должны решить, где применять ограничения целостности ваших данных и где запрашивать их / делать интересные вещи с ними.

Как уже упоминалось, некоторые серверы баз данных не поддерживают рекурсивные запросы; однако, если вы собираетесь запросить базу данных, а затем построить дерево в коде - тогда это спорный вопрос.

Но даже если вы можете сделать это в SQL - вы действительно хотите? SQL отлично подходит для некоторых вещей, но не для всех.

Основная задача должна состоять в том, чтобы позволить базе данных делать то, в чем она хороша - что в данном случае звучит как Решение 1.

1 голос
/ 01 ноября 2011

Некоторые базы данных имеют рекурсивные запросы, например, конструкция CONNECT BY в Oracle. В этом случае я бы, конечно, выбрал 1.

Но даже если нет, я думаю, что данные будут чище, если вы предоставите каждому своего менеджера, если это действительно структура данных. Вам нужно выполнить несколько запросов, чтобы все менеджеры добрались до генерального директора, или вы должны получить все данные и построить дерево на любом языке программирования, который вы используете. Но у вас та же проблема, если каждый человек получает список менеджеров. Вам понадобится некоторый программный интеллект, если вы хотите построить дерево из этих данных. Если у вас нет Oracle, то есть. ;)

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

...