Должны ли итоги быть денормализованы? - PullRequest
4 голосов
/ 04 марта 2009

Я работаю над сайтом с простой нормализованной базой данных.

Существует таблица с именем Pages и таблица с именем Views. Каждый раз, когда страница просматривается, уникальная запись этого просмотра записывается в таблицу представлений.

При отображении страницы на сайте я использую простую СЧЕТЧИК MySQL (), чтобы получить общее количество просмотров для отображения.

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

Стоит ли денормализовать таблицу «Страницы», добавив столбец «Страницы», в котором содержится общее количество просмотров для каждой страницы? Или есть эффективный способ сделать запрос для 10 самых популярных страниц?

Ответы [ 5 ]

8 голосов
/ 04 марта 2009
   SELECT p.pageid, count(*) as viewcount FROM 
   pages p
   inner join views v on p.pageid = v.pageid
   group by p.pageid
   order by count(*) desc   
   LIMIT 10 OFFSET 0;

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

3 голосов
/ 04 марта 2009

Это зависит от уровня информации, которую вы пытаетесь поддерживать. Если хочешь записать кто смотрел когда? Тогда отдельный стол в порядке. Иначе, столбец для Представлений - путь. Кроме того, если вы сохраните отдельный столбец, вы обнаружите, что таблица будет блокироваться чаще, поскольку при каждом просмотре страницы будет пытаться обновить столбец для соответствующей строки.

Select pageid, Count(*) as countCol from Views
group by pageid order by countCol DESC
LIMIT 10 OFFSET 0;
1 голос
/ 04 марта 2009

Нормализация базы данных - это самый эффективный / наименее избыточный способ хранения данных. Это хорошо для обработки транзакций, но часто напрямую конфликтует с необходимостью эффективного вывода данных снова. Проблема обычно решается путем получения производных таблиц (индексы, материализованные представления, сводные таблицы ...) с более доступными, предварительно обработанными данными. (Немного устаревшее) модное слово здесь - хранилище данных.

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

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

1 голос
/ 04 марта 2009

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

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

0 голосов
/ 04 марта 2009

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

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

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

Денормализация определенно может быть использована для повышения производительности.

- Kris

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...