Alixx
@Alixx

Как лучше всего хранить данные о группах в бд?

Здравствуйте.
Проектирую бд под следующую задачу.
У каждого пользователя есть рабочие и управляющие, из них нужно формировать группы и направлять их на работу.
Каждый рабочий имеет разную производительность от 1 до 5. Управляющие все одинаковы и равноценны.
Они все безликие. Нету даже имени. Поэтому нет смысла делать запись для каждого рабочего и каждого управляющего.
У пользователя указывается кол-во рабочих каждого уровня производительности и кол-во управляющих.

Группы нужно формировать из 1 управляющего и из 1-3 рабочих.
На одну работу можно назначить несколько групп.

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

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

Таблица groups:
id_user,
managers,
workers_1,
workers_2,
workers_3,
workers_4,
workers_5,
formed_groups.

И ещё есть таблица jobs с данными о запущенных работах.
Всё типа int, кроме formed_groups - у него тип json.
В formed_groups хранятся списки сформированных групп. Для работающих ещё указывается id соответствующей работы из jobs.
Ну а в таблице работ jobs не будет информации о работающих группах.

----
Рассматриваю ещё такой вариант:
Всё почти то же самое, что в первом варианте. Только теперь в groups->formed_groups храним данные о свободных группах. А данные о работающих группах храним в jobs, также в json.

Возникает вопрос, как лучше всего хранить эти данные в бд? В приоритете производительность.
  • Вопрос задан
  • 885 просмотров
Решения вопроса 1
Alixx
@Alixx Автор вопроса
Мне подошла такая схема:
groups
    user_id: foreign key -> users.id
    manager_id: int
    user_id, manager_id: primary key
    is_deleted: boolean
    work_id: foreign key -> works.id, nullable
    worker_1_rarity: int, nullable
    worker_2_rarity: int nullable
    worker_3_rarity: int, nullable

users_groups_sets
    id_user: foreign key -> users.id (primary key)
    managers_count: int // кол-во всех управляющих
    workers_1_count: int // кол-во всех рабочих 1 уровня производительности и т.д.
    workers_2_count: int
    workers_3_count: int
    workers_4_count: int
    workers_5_count: int

Т.к. группа не может быть сформирована без управляющего, то id управляющего можно сделать идентификатором бригады. А в группе надо знать, какого уровня рабочие там собраны, вот и указываем (для 3х возможных мест рабочих) уровни рабочие, которые были сформированы в группу.
Свободные группы - те, в которых work_id is null и хотя бы один из worker_X_rarity is not null.
Работающие группы - где work_id is not null.
Свободные управляющие - где все worker_X_rarity is null.

В интерфейсе для формирования групп надо получать данные о всех группах, управляющих и рабочих. Поэтому тут два запроса всего - из groups и users_groups_sets получить все записи по id пользователя. На уровне приложения уже формируем все данные: о свободных и работающих группах, о свободных управляющих и рабочих.

Удалять прямо из сформированной группы нельзя ни рабочих, ни управляющего.
Когда рабочего добавляем юзеру, то добавляем 1 к workers_X_count, где X - это уровень производительности этого рабочего.
Когда удаляем, то отнимаем 1 от нужного workers_X_count.
С добавлением управляющего, также +1 и, если есть запись с is_deleted == true, то просто у неё ставим false, иначе создаём запись в groups.
Когда удаляем, то также -1, а в groups у первой найденной записи, где все worker_X_rarity is null, ставим is_deleted в true.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
saboteur_kiev
@saboteur_kiev
software engineer
table resources
user_name, user_id, w1_total, w1_used, w2_total, w2_used, w3_total, w3_used, w4_total, w4_used, w5_total, w5_used

table groups
user_id, group_name, w1,w2,w3,w4,w5, current_task
Ответ написан
Комментировать
NikFaraday
@NikFaraday
Student full-stack Developer
Вот такой вариант есть

task
    id:guid unique

groups
    id:guid unique
    task_fk:guid <--

manager:
    id:guid unique
    group_fk:guid unique

worker
    id:guid unique
    group_fk:guid <--


Обратите внимание на строку, где указана стрелочка. Отсутствие ключевого слова unique даёт возможность нескольким записям в этой таблице быть связанным с другой таблицей (groups) либо, другими словами, связь one-to-many. Наличие unique в таблице managers явно указывает, что только один менеджер может быть привязан в конкретной группе, другими словами, это связь one-to-one, где внешний ключ (foreign key) находится в таблице managers.

Группы нужно формировать из 1 управляющего и из 1-3 рабочих.

Это уже часть бизнес-логики, это не имеет отношения к проектирования БД
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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