Счетчик обращений к странице - я перенапрягаю базу данных?

Я построил простой счетчик посещений на своем веб-сайте (PHP и MySQL, используя Codeigniter в качестве фреймворка).

Это таблица, которую я использую:

CREATE TABLE page_hits (id INT NOT NULL AUTO_INCREMENT, page_url VARCHAR(350) NOT NULL, ip VARCHAR(11) NOT NULL, hits INT NOT NULL, `date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP  NOT NULL, PRIMARY KEY (id));

При каждой загрузке страницы я проверяю, существует ли в таблице комбинация page_url & ip. Если это так, я увеличиваю значение hits на 1. Если нет, я создаю новую строку в таблице. Отметка времени предназначена для обеспечения определенной задержки между счетчиками попаданий, чтобы не считать обновление страницы новым попаданием.

Все работает нормально, но я боюсь, что могу перегрузить свою базу данных ... Менее чем за 24 часа у меня более 6500 строк в page_hits таблице.

Итак, мой вопрос: каковы риски наличия такой быстро растущей таблицы в моей базе данных? (проблемы с производительностью? превышение ограничения размера базы данных?)


person einav    schedule 16.03.2015    source источник
comment
Вы не рискуете, если ваши таблицы нормализованы и проиндексированы правильно.   -  person Jay Blanchard    schedule 16.03.2015


Ответы (1)


Позвольте мне начать с переписывания вашей однострочной команды SQL:

CREATE TABLE page_hits 
(id       INT NOT NULL AUTO_INCREMENT, 
 page_url VARCHAR(350) NOT NULL, 
 ip       VARCHAR(11) NOT NULL, 
 hits     INT NOT NULL, 
 date     TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 
 PRIMARY KEY (id))

Теперь я вижу, что там.

Ваш стол не сложный, но он будет быстро расти. Это не будет проблемой, если вы ничего с этим не сделаете. Другими словами: добавление строк в таблицу не проблема, даже если у вас миллион строк.

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

Как добавить индексы в таблицы MySQL?

Во-вторых, вы можете подумать о нормализации таблицы и избавиться от ненужной информации. Например, эти три таблицы меньшего размера:

CREATE TABLE page_hits 
    (id         INT NOT NULL AUTO_INCREMENT, 
     page_id    INT NOT NULL, 
     client_id  INT NOT NULL, 
     hits       INT NOT NULL, 
     PRIMARY KEY (id))

CREATE TABLE pages 
    (id       INT NOT NULL AUTO_INCREMENT, 
     page_url VARCHAR(350) NOT NULL, 
     PRIMARY KEY (id))

CREATE TABLE clients 
    (id       INT NOT NULL AUTO_INCREMENT, 
     ip       VARCHAR(11) NOT NULL, 
     date     TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 
     PRIMARY KEY (id))

Здесь page_id относится к таблице pages, а client_id относится к таблице clients. Вам придется самостоятельно добавлять индексы. Я бы избавился от столбца date и решил эту проблему с помощью файла cookie. Обратите внимание, что новые таблицы можно легко расширить, чтобы они содержали больше информации, не слишком быстро становясь слишком большими.

person KIKO Software    schedule 16.03.2015
comment
Спасибо! и прошу прощения за плохую компоновку SQL в моем исходном сообщении. - person einav; 16.03.2015
comment
Это было отклонено. Если так и будет, я удалю этот ответ. Я был бы полезен, если бы знал, что сделал не так, чтобы я мог улучшить себя. - person KIKO Software; 16.03.2015
comment
Я добавил индексы для page_url и ip, поскольку это те поля, которые я буду запрашивать. Но я не понимал, в чем преимущество использования трех отдельных таблиц вместо той, которую использую я. Улучшит ли эта нормализация производительность? - person einav; 16.03.2015
comment
И я не знаю, кто вас проголосовал против и почему. Я только что проголосовал за твой ответ. - person einav; 16.03.2015
comment
Да, очень странно. Это случается очень часто, отрицательные голоса без какой-либо обратной связи. Это нехорошо. Спасибо за голос. - person KIKO Software; 16.03.2015
comment
Что касается вашего вопроса: подумайте, каждое попадание кем-либо будет создавать новую строку в таблице page_hits. Удалив page_url и ip из этой таблицы, я сделал каждую строку намного меньше. И две другие таблицы (pages и clients) не будут расти так быстро, потому что вы повторно используете строки. В этом суть нормализации. - person KIKO Software; 16.03.2015
comment
Истинный. Каждая строка в page_hits теперь будет меньше. Но при каждой загрузке страницы мне придется запрашивать 2 таблицы (clients & pages) и добавлять новую строку (или обновлять существующую) в третью таблицу (page_hits). Кроме того, page_hits будет использовать 2 внешних ключа. Разве это не обременяет базу данных? - person einav; 16.03.2015
comment
Вы должны проанализировать, как будут использоваться ваши данные, и соответствующим образом структурировать базу данных. Нормализация уместна во многих случаях, но не во всех. - person rjdown; 16.03.2015
comment
Я должен согласиться с rjdown, все зависит от того, что вы делаете. Да, в этом случае вам придется больше обрабатывать, но ваши таблицы останутся меньше. На сервере с высоким трафиком это лучший вариант. Если у вас мало посетителей и медленный сервер, ваша собственная таблица будет более эффективной. - person KIKO Software; 16.03.2015
comment
Как вы определяете небольшое количество посетителей и высокий трафик? Моя исходная таблица page_hits теперь увеличивается примерно на 7000 строк каждые 24 часа. - person einav; 16.03.2015
comment
И последнее, @KIKOSoftware. Если бы я использовал предложенную вами структуру из трех таблиц, какие столбцы вы бы посоветовали мне проиндексировать? И следует ли мне определять page_id и client_id как внешние индексы? - person einav; 16.03.2015
comment
Столбцы, которые вы используете в разделе WHERE команд SELECT, обязательно должны быть проиндексированы. 7000 строк в день, это 2,5 миллиона в год. Если вы собираете данные в течение нескольких лет, я думаю, это многовато. MySQL может легко обрабатывать 10 миллионов строк, но если вы посмотрите на размер файла базы данных, вы можете понять, почему это может стать проблемой. Предположим, ваша строка составляет 400 байтов, умножьте это на 10 миллионов, это 4 ГБ. На мой взгляд, слишком большой. Мой ряд будет примерно 1/20 этого размера. И все это без индексов, которые только увеличивают размер файла. - person KIKO Software; 16.03.2015