Структура базы данных для ведения статистики по дням, неделям, месяцам, годам

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

Мне нужно просто просто увеличивать значения в полях на 1 в БД каждый раз, когда происходит действие. Поэтому я могу поднять дату каждый день, каждую неделю, каждый месяц и год. Как должна быть структурирована моя БД? Извиняюсь, если это простой вопрос для большинства. Было бы также здорово, если бы эта структура могла быть расширяемой, чтобы ее можно было разделить на другие категории.

У меня есть проблемы с каждым месяцем, состоящим из нескольких дней, и в эти дни меняются каждый календарный год.

Спасибо всем за любую помощь или руководство.

Дополнительная информация: Linux Machine, использующая PHP и MySQL

Ответ 1

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

insert into activities (activity_date, activity_info) 
values (CURRENT_TIMESTAMP, 'whatever');

Теперь ваши отчеты очень просты:

select count(*) from activities
where activity_date between '2008-01-01' and '2008-01-07';

или

select YEARWEEK(`activity_date`) as theweek, count(*)
group by theweek

Ответ 2

Вы можете просто добавить записи в таблицу и SELECT с помощью агрегатных функций.

Если по какой-то причине вам необходимо сохранить агрегированную статистику, вы можете использовать:

CREATE TABLE aggregates (type VARCHAR(20), part VARCHAR(10) NOT NULL PRIMARY KEY, activity INT)

INSERT INTO aggregates (type, part, activity)
VALUES ('year', SUBSTRING(SYSDATE(), 1, 4), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

INSERT INTO aggregates (type, part, activity)
VALUES ('month', SUBSTRING(SYSDATE(), 1, 7), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

INSERT INTO aggregates (type, part, activity)
VALUES ('day', SUBSTRING(SYSDATE(), 1, 10), 1)
ON DUPLICATE KEY UPDATE activity = activity + 1

Это автоматически обновит существующие строки и при необходимости добавит несуществующие.

Ответ 3

  • таблица событий: id, идентификатор активности, datetime, userid.
  • таблица пользователей: id, имя пользователя и т.д.
  • таблица действий: id, название действия и т.д.

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

Ответ 4

Для начала вы могли бы представить себе одну таблицу, так как это была бы самая нормализованная форма. В таблице будет просто запись для каждого полученного вами удара, причем каждая строка содержит дату/время этого удара.

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

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

Это, вероятно, потребует создания строки для каждого часа. По-прежнему будет намного быстрее выполнить запрос на день или месяц, если вы выберете максимум 24 строки в день.

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

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

Ответ 5

Ответ Тони Эндрюса является самым простым, однако структура снежинок иногда используется в приложениях хранилища данных: таблица, которая учитывает все виды деятельности, другую для деятельности в день, другую для мероприятий в месяц и третью для деятельности в год, При такой структуре активность между любыми двумя датами может быть рассчитана очень эффективно. https://en.wikipedia.org/wiki/Snowflake_schema

Ответ 6

Используйте схему схемы звездочки. (или, возможно, дизайн снежинки).

Дизайн Star-Schema

В результате вы введете таблицу фактов для каждого нового действия. См. Предложение Тони.

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

Ваш вопрос относится к таблице измерений временных рамок. Назовите это "Альманах". Выберите гранулярность. Скажем, день. У альманаха будет один ряд в день. Первичным ключом может быть дата. Ваша таблица фактов должна включать этот первичный ключ в качестве внешнего ключа, чтобы упростить объединение. (Не имеет значения, объявите ли вы его как внешний ключ, что влияет только на ссылочную целостность во время процесса обновления.)

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

Здесь приведена статья, сравнивающая ER и DM. Я необычен тем, что мне нравятся оба метода, выбирая подходящий метод для соответствующей задачи.

http://www.dbmsmag.com/9510d05.html

Ответ 7

Ваш вопрос относится к таблице измерений временных рамок. Назовите это "Альманах". Выберите гранулярность. Скажем, день. У альманаха будет один ряд в день. Первичным ключом может быть дата. Ваша таблица фактов должна включать этот первичный ключ в качестве внешнего ключа, чтобы упростить объединение. (Не имеет значения, объявите ли вы его как внешний ключ, что влияет только на ссылочную целостность во время процесса обновления.)