0

У меня есть потребность в решении, которое позволит мне отслеживать каждый клик (и ссылку, а также дату) в веб-приложении (PHP5/MySQL5.7). Самое простое решение, очевидно, простая таблица:Лучшая структура для таблицы MySQL для хранения статистических данных

CREATE TABLE stats_data (
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    log_date DATETIME NOT NULL DEFAULT NOW(), 
    link VARCHAR(512) NOT NULL 
) 

Я не такой, как это масштабируется производительность мудрым, как ожидается, количество кликов за день вполне может пойти выше 10000.

  1. Это надежное решение, скажем, через 5 месяцев хранения данных?
  2. Какие оптимизации могут сделать это решение более эффективным??
  3. Если нет, то какой подход был бы лучшим решением для этого?
+2

изменение 'link VARCHAR (512)' to 'link_id INT' - одна очевидная оптимизация. –

+1

Это действительно зависит от запросов, которые вы будете использовать. Опишите их или покажите нам предварительные утверждения SELECT. (1.5M записей через 5 месяцев не много.) –

+0

Проблема была решена, как показано принятым ответом ниже. Спасибо. –

ответ

1

В основном это зависит от вашего прецедента. Какие запросы вы хотите использовать для этого набора данных?

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

Если вы хотите придерживаться MySQL, у меня есть несколько советов о том, как сделать это решение более надежным.

  1. Dont сохранить каждый клик в базе данных каждый раз щелкнул, но сохраняет его в кэш (Memcached, например) и один раз каждый час сохранить в MySQL
  2. сделать собственную таблицу для каждого месяца, чтобы не сделать поиск в одной большой Таблица. А резервное копирование этой таблицы каждый месяц.
+0

Вариант использования, ну, вытаскивая из него статистические данные. В моем веб-приложении я хочу позволить пользователю увидеть (например) количество кликов в определенный месяц, день или пользовательский период. Запросы (кроме вставки) будут в большинстве случаев получать строки в определенном диапазоне дат. 1. Вглядываясь в него, благодарю. 2. Мне нравится эта идея, спасибо еще раз. –

+1

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

+1

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

1

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

В зависимости от того, насколько точны ваши данные, вы также можете агрегировать их в другую таблицу в maby, выполняющую какую-либо ночную работу (запланированный sp должен работать). Таким образом, у вас может быть таблица, в которой вы, например, можете указать, сколько раз была нажата ссылка за определенный интервал, день или час или что-то, что вам подходит. Я использовал этот подход на работе, где мы храним статистические данные на вызовах веб-сервисов в приложении с очень большой нагрузкой, и он отлично работает, без каких-либо проблем с производительностью.

0

Там есть пара думает, что вы можете сделать, чтобы обеспечить производительность:

Разделив данные по столбцам по дате, вы можете «разделить» данные по часам/день/неделя/месяц/год ... независимо от того, что вы хотите ...

Пример:

CREATE TABLE members (
firstname VARCHAR(25) NOT NULL, 
lastname VARCHAR(25) NOT NULL, 
username VARCHAR(16) NOT NULL, 
email VARCHAR(35), 
joined DATE NOT NULL 
) 
PARTITION BY RANGE(YEAR(joined)) (
    PARTITION p0 VALUES LESS THAN (1960), 
    PARTITION p1 VALUES LESS THAN (1970), 
    PARTITION p2 VALUES LESS THAN (1980), 
    PARTITION p3 VALUES LESS THAN (1990), 
    PARTITION p4 VALUES LESS THAN MAXVALUE 
) 

Поэтому, представляя себе, что вы разделяете данные по неделям, при поиске с помощью журнала с датой, равной «2016-08-25», что запись будет просматриваться только на бревнах даты между «2016-08-22» и «2016-08-28».

Я надеюсь, что это может вам помочь.

+0

Спасибо! Вероятно, это то, что я ищу. Ответ выше предложил создать таблицы по месяцам. Легко это сделать. Но разметка выглядит более элегантно, предполагая, что она достигает той же цели? другими словами, может ли «раздел» удержать пару миллионов строк (то есть данные, пригодные для месяца в месяц), я полагаю? Благодарим вас за подсказку, BTW. Я также переместил ссылки на другую таблицу и сделал ссылку link_id своим внешним ключом. –