Как структурировать базу данных для ежедневного журнала событий? - PullRequest
0 голосов
/ 12 января 2019

Я храню данные, которые регистрируют, зарегистрировал ли пользователь свою посещаемость за определенный день. Некоторые дни не важны (праздники, выходные), поэтому они также сохраняются.

Два требования следующие:

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

Сейчас мне кажется, что я столкнулся с двумя вариантами хранения данных, каждый из которых имеет свои преимущества / недостатки:

Вариант 1: две таблицы

Таблица calendar - Отслеживает дни, которые не учитываются

date       | log |
-----------+-----|
2019-01-10 | DNL | // "Do Not Log" - holiday etc.
2019-01-12 | NB  | // "Non-business day"
2019-01-13 | NB  |

Таблица logs - Отслеживает успешные журналы посещаемости

user_id | date       |
--------+------------|
      1 | 2019-01-08 |
      1 | 2019-01-09 |
      2 | 2019-01-09 |

// It's implied that user #2 missed their log on Jan. 8

Преимущества:

  • Данные эффективно хранятся.
  • Подсчет журналов пользователей и не считая дней тривиален.

Задача:

  • Зная, сколько дней было пропущено, не очевидно.

Вариант 2: одна таблица (что я пробовал)

Таблица calendar - Отслеживает журналы и дни, которые должны учитываться и не учитываться

date       | user_id | log  |
2018-01-09 |       1 |    1 | // Counted, logged
2019-01-10 |       1 |  DNL | // Not counted
2019-01-11 |       1 |   NB | // Not counted
2019-01-09 |       2 | NULL | // Counted, missed log

Преимущества:

  • Число пропущенных дней по сравнению с зарегистрированными днями тривиально (используется для расчета общего процента). Количество дней в календаре является явным.

Задача:

  • Добавить новые записи в календарь сложно, если:
    • Календарь увеличивается в длину.
    • Добавлены новые пользователи.
  • В таблице есть пробелы (где log == NULL), что делает обход медленнее, чем в Варианте 1.

У меня такой вопрос: есть ли способ либо использовать вариант 1 и каким-либо образом кодировать количество пропущенных журналов, либо есть какой-то другой способ хранения данных, который удовлетворяет обоим требованиям? Я пробовал использовать Вариант 2, хотя масштабирование стало довольно сложной задачей. Заранее спасибо за любой совет.

1 Ответ

0 голосов
/ 13 января 2019

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

Допустим, вы хотите выяснить, в какие дни пользователь X пропустил между start-date и end-date.

  1. Получите список всех особых дней между start-date и end-date.
  2. Получить список всех дней, в которые пользователь входил в систему, между start-date и end-date.
  3. Выполните следующие действия:

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

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

Я не гуру SQL, но я был бы удивлен, если бы вы не могли сделать это с помощью одного SQL-запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...