Вопрос проектирования базы данных SQL: отношение «один к одному» против полного разделения - PullRequest
0 голосов
/ 09 декабря 2018

Я проектирую простую базу данных для размещения двух типов данных:

  • Задача (единица работы): отношения «один на один» с пользователями
  • Статистическая статистика после выполнения задачи(Сводные данные о выполненной работе). Отношения «один к одному» с пользователями.

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

Вот пример со значениями данных для ясности:

Задача:

{
  id: {uuid}
  user: {user_id}
  create_time: {timestamp}
  last_modified_time: {timestamp}
  description: {string}
  completion_time: {int}
  length: {int}
  difficulty: {int}
  cost: {int}
  ...
}

Общая статистика после выполнения задачи

{
  id: {uuid}
  user: {user_id}
  total_completed_tasks: {int}
  avg_completion_time: {double}
  avg_task_length: {double}
  avg_task_difficulty: {double}
  avg_task_cost: {double}
  ...
}

Есть лилучший / более умный способ спроектировать состояние для этого типа данных.Вещи, которые я рассмотрел:

  • Не удалять задачу после завершения (просто пометьте ее как завершенную) и установить отношение многие (задача) к одному (совокупная статистика)
  • Не агрегироватьстатистика и создание отношения один-к-одному между статистикой задачи и отдельной публикацией задачи, а затем запрашивает статистическую таблицу и объединяет ее по мере необходимости

1 Ответ

0 голосов
/ 09 декабря 2018

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

Пример в PostgreSQL:

create or replace view task_statistics as
select user
, count(distinct id) as total_completed_tasks
, avg(completion_time) as avg_completion_time
, avg(length) as avg_task_length
, avg(difficulty) as avg_difficulty
, avg(cost) as avg_cost
from task
group by user;
...