powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Проектирование и использование иерархий в базах
12 сообщений из 12, страница 1 из 1
Проектирование и использование иерархий в базах
    #37027988
spandex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый вечер.

Хотелось бы узнать кто и как из разработчиков решал проблему описанную ниже.

Есть база данных Firebird. Условно в ней 3 таблицы.

1. Сотрудники (USERS: ID int, NAME varchar)
2. Подчинения (USERS_TREE: ID int, USER_ID int, MASTER_ID int, FCODE varchar)
3. Данные по сотрудникам (DATA: ID int, USER_ID int, FDATE date, Amount int)

В таблице подчинений хранится информация о подчинении сотрудников в предприятии.
В таблице DATA содержатся опр.данные по всем сотрудникам.

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

Как более грамотно построить SQL запрос чтобы можно было выбрать из таблицы DATA данные только по подчиненным.

На настоящий момент я ввел поле FCODE тип - строка. Она состоит из макс.60 блоков символов по 4 шт (т.е. 240 символов). Один блок - это один сотрудник.

Например:

USERS_TREE: (ID, USER_ID, MASTER_ID, FCODE)

1, 1, 0, 0001
2, 2, 0, 0002
3, 3, 2, 0002|0003 (подчиненый для USER_ID=2)
4, 8, 2, 0002|0008 (подчиненый для USER_ID=2)
5, 9, 3, 0002|0003|0009 (подчиненый для USER_ID=3)
...

SQL запрос пишется сл.образом:
Для сотрудника узнаем его FCODE, допустим 0018, тогда подчиненых и его в т.ч.можно вывести с помощью INNER JOIN от DATA к USERS_TREE при UT.FCODE LIKE '0018%'.

Вроде ничо, НО бывает так что люди уходят или переводятся, а у них много подчиненных.
Возникает необходимость лазить по базе и менять FCODE для всех его подчиненных.

Какие есть альтернативные варианты для такой иерархии?
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37028535
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spandexКакие есть альтернативные варианты для такой иерархии?
Ну, до тех пор, пока в FB не появятся рекурсивные запросы, зло неизбежно :)

По мне, наиболее нормальный вариант - сделать таблицу-развязку "все прямые и косвенные подчинённые человека" и обновлять её по необходимости. А вообще - поищите книжку по ключевым словам SQL antipatterns, была неплохая вещь, где среди прочего разбирались решения этой задачи и плюсы-минусы каждого.
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37028639
Фотография StalkerS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поиск детей в дереве - стандартная задача, решение зависит от того, что требуется от системы. Если нужен быстрый селект по большим ветвистым деревьям - то можно попробовать метод селко. Если быстрая вставка - то можно и циклами (при отсутствии встроенной поддержки иерархий в субд).
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37028784
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerspandexКакие есть альтернативные варианты для такой иерархии?
Ну, до тех пор, пока в FB не появятся рекурсивные запросы, зло неизбежно :)Они уже давно появились .
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37028840
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ваша основная ошибка, spandex, в постановке задачи. Люди, если вам в детстве забыли об этом сказать, равны, никто никому не подчиняется. А вот функциональные или административные роли людей - да, имеют иерархии, это правда. Ваша иерархия называется "штатное расписание". Административная структура лавки - штатное расписание - иерархия должностей. Персона - занимает должность.

Возможны изменения двух типов: связанные с реорганизацией лавки или миграцией кадрового состава, что и легко администрируется, и просто укладывается в историю изменений.
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37028867
Naf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37029338
spandex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сдается мне что мой способ все такие легче.
Но я все равно изучу предложенные вами материалы для следующих работ.

Выражаю особую благодарность: Senya_L, Naf и softwarer.
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37029378
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spandex,

Изначально не вчитывался в Вашу задачу, но имхо Вам достаточно одной древовидной таблицы "Сотрудники".
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37029610
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо известное, но, к сожалению, не доступное в FB и других РСУБД, решение: здесь два объекта и две связи между ними.

Сотрудник(U) {Имя(N),сторока}
Данные по сотруднику(D) {Некая дата(FD),дата; Некое количество(A),число}

Сотрудник - Имеет подчиненного/Является подчиненным(1) -> Сотрудник
Сотрудник - Имеет/Относятся к(1) - Данные по сотруднику

Например, для сотрудника id все подчиненные с учетом иерархии:

SELECT U{N},D{FD,A}
FROM U(1)-U(1)-D
WHERE ^U(-1):ID=id

а только непосредственно подчиненные:

WHERE U(-1):ID=id
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37029617
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LИзначально не вчитывался в Вашу задачу, но имхо Вам достаточно одной древовидной таблицы "Сотрудники".
Из постановки, действительно, не совсем ясна объективная необходимость Данных по сотруднику.
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37030697
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SET SQL DIALECT  3 ;
CREATE TABLE TEST 
(
    -- ID сотрудника
    ID         INTEGER,
    -- ID его начальника (другой TEST.ID)
    PARENT_ID  INTEGER,
    NAME       VARCHAR( 100 )
);

INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 1 , NULL, 'REC 1');
INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 2 , NULL, 'REC 2');
INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 11 ,  1 , 'REC 11');
INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 12 ,  1 , 'REC 12');
INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 121 ,  12 , 'REC 121');
INSERT INTO TABLE TEST(ID, PARENT_ID, NAME) VALUES( 13 ,  1 , 'REC 13');

Т.е. в таблице хранится вот такая иерархия:
-1
--11
--12
---121
--13

Список всех сотрудников, прямо или косвенно подчиненных сотруднику 1:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
WITH RECURSIVE n(lvl, id, name) AS (
    SELECT  0  lvl, id, name
    FROM test
    WHERE id =  1 
    UNION ALL
    SELECT n.lvl +  1 , nplus1.id, nplus1.name
    FROM test as nplus1, n
    WHERE n.id = nplus1.parent_id)
SELECT lvl, id, name FROM n;

Список всех начальников сотрудника 121:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
WITH RECURSIVE n(lvl, parent_id, id, name) AS (
    SELECT  0  lvl, parent_id, id, name
    FROM test
    WHERE id =  121 
    UNION ALL
    SELECT n.lvl -  1 , nminus1.parent_id, nminus1.id, nminus1.name
    FROM test as nminus1, n
    WHERE n.parent_id = nminus1.id)
SELECT lvl, id, name FROM n;

Иерархические запросы на Firebird 2.5.
...
Рейтинг: 0 / 0
Проектирование и использование иерархий в базах
    #37031119
spandex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnSparrow, спасибо, то, что надо.

Насчет объективной необходимости.

Есть штатное расписание и таблица отработанных сотрудниками часов за месяц.
Каждый руководитель должен иметь возможность контроля опоздания или уходов сотрудников (за свой отдел/управление/филиал) раньше времени с рабочего места. Также ведется контроль сверхурочных.

В автозапуске висит прога, которая регистрирует вкл. и выкл. сис.блока. На основе этих данных расчитывается кол-во отработанных часов.

Было требование чтобы руководители одного и того же уровня не могли видеть данные по подчиненым друг друга, а только своих и кто подчинен им и т.д.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Проектирование и использование иерархий в базах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]