Каждый раз, когда вы видите столбцы с номерами в их именах, такие как column_1, column_2, column_3 ... ваш флаг «ужасного дизайна базы данных» должен подниматься. (К вашему сведению, здесь вы нарушаете 1NF, в частности, вы повторяете группы по столбцам )
Теперь, возможно, что такая реализация может быть приемлемой (или даже необходимой) в производстве, но концептуально это определенно неправильно.
Как говорит Герт, концептуально достаточно двух таблиц. Если производительность является проблемой, вы можете денормализовать данные для еженедельной / ежемесячной статистики, но все равно я не буду моделировать их, как указано выше, но я сохраню
CREATE TABLE base_stats ( link_id INT, click_time DATETIME )
CREATE TABLE daily_stats ( link_id INT, period DATETIME, clicks INT )
Вы всегда можете агрегировать с
SELECT link_id, count(*) as clicks, DATE(click_time) as day
FROM base_stats
GROUP_BY link_id, day
, который можно запускать периодически для заполнения daily_stats. Если вы хотите поддерживать его в актуальном состоянии, вы можете реализовать его в триггерах (или, если это действительно необходимо, сделать это на стороне приложения). При необходимости можно также денормализовать данные на разных уровнях (путем создания большего количества агрегированных таблиц или введения другого столбца в таблицу агрегированных данных), но это может быть преждевременной оптимизацией.
Приведенный выше дизайн намного чище для будущего специального анализа (произойдет со статистикой). Другие преимущества смотрите в википедии о повторяющихся группах.
EDIT:
Хотя решение с двумя таблицами base_stats
и aggregated_stats
принято, со следующей стратегией:
- вставлять каждый клик в
base_stats
- периодически агрегирует данные из
base_stats
в daily_stats
и очищает все детали
это не может быть оптимальным решением.
Основываясь на обсуждениях и разъяснениях требований, кажется, что таблица base_stats
не нужна. Также следует изучить следующий подход:
CREATE TABLE period_stats ( link_id INT, period DATETIME, ...)
Обновление легко с
UPDATE period_stats
SET clicks = clicks + 1
WHERE period = @dateTime AND link_id = @url AND ...
Стоимость обновления этой таблицы при правильной индексации столь же эффективна, как и вставка строк в base_table
, и любую ее также легко использовать для анализа
SELECT link_id, SUM(clicks)
FROM period_stats
WHERE period between @dateTime1 AND @dateTime2
GROUP BY ...