Ответ 1
Здесь я рекомендую на основе ваших серверов/сотрудников/данных, если эти серверы. Поскольку вы используете 1 сервер (и 1 резервное копирование), емкость вашего накопителя должна быть достаточной на некоторое время, если вы не хотите архивировать полные данные на этом сервере. Данные могут быстро расти, и я думаю, что увеличить емкость или архивировать данные где-то еще.
Теперь, поскольку у вас есть много людей, которые могут запрашивать данные отчетов, основная идея состоит в том, чтобы как можно быстрее извлекать данные, чтобы убедиться, что вы не блокируете записи (особенно, если вы используете таблицы myisam - блокировку таблицы против innodb, которая имеет блокировку на уровне строк).
Используйте свой индекс (уникальный, если вам нужно) с умом и храните свои данные максимально эффективно, используя метку времени.
То, что вы также можете сделать, - это обобщить ваши данные, которые упростят ваши запросы. Хотя, это не обычная практика в базах данных, поскольку она не соответствует нормальным формам. Вы можете получить отличную производительность, но это боль для поддержания.
Честно говоря, cron, который запускается каждую минуту, прекрасен, так как у вас есть время, когда вы сохраняете запись, но можно получать данные каждую секунду. Я рекомендую убедиться, что когда вы получите запись, вы помечаете эту запись как "обработанную" или какой-то другой статус, чтобы не брать эту запись дважды.
Теперь, когда вы суммируете свои данные, убедитесь, что вы оптимизировали свои запросы, и вы также можете проверить, что будет выводить explain, а затем сделать решение.
РЕДАКТИРОВАТЬ: Подведение итогов (что не соответствует нормализации базы данных) даст вам отличную производительность, так как вы только запрашиваете записи без использования агрегатных функций и объединяете таблицы с минимальным предложением where.
Пример:
98 views on product 1
1 order
21 referral click from clients
2 added to wishlist
может быть:
SELECT
views, orders, referral, whishlist
FROM
summarize_stats_20111201 /* daily table for example */
WHERE
`time` between 1322791200 /*2011-12-01 21:00:00*/ AND 1322791260 /*2011-12-01 21:01:00*/;
views
имеет общее количество просмотров, в этом примере 98
orders
имеет общее количество заказов, в этом примере 1
referral
имеет общую сумму обращения, в этом примере 21
wishlist
имеет общее количество списка желаний, в этом примере 2
Это рассчитанные данные в сводной таблице (вот почему я сказал, что "не соблюдает нормализацию базы данных", потому что вы никогда не вычисляете данные в СУБД), но если вам нужны данные мгновенно, вы можете это сделать.
ИЗМЕНИТЬ 2: Здесь приведен пример сохранения этого решения:
У вас есть cronjob, который поддерживает таблицы. Его задача - создать таблицу на следующий день или что вам нужно.
// in php
$date = date('Ymd', strtotime('+1 day')); // for daily table
$sql = 'CREATE TABLE IF NOT EXISTS the_database.summarize_stats_" . $date . ";
Итак, когда вы вставляете, убедитесь, что у вас есть правильное имя таблицы, и вы используете ВКЛЮЧЕН КЛЮЧ DUPLICATE
// in php
$sql = 'INSERT INTO TABLE summarize_stats_20111201 SET /* all the fields you need */ ON DUPLICATE KEY views = views + 1;
например, если вы хотите увеличить представление
Я также забыл, что если вам нужно запросить 1 неделю данных, вам нужно будет создать таблицу merge. Таким образом вы можете сделать что-то вроде:
SELECT
views, orders, referral, whishlist
FROM
summarize_stats_2011 /* yearly merge table for example */
WHERE
`time` between 1322272800 /*2011-11-25 21:00:00*/ AND 1322791260 /*2011-12-01 21:01:00*/;
Таким образом, вам не нужно UNION ALL
тон запросов.