Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: проектирование БД
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » проектирование БД

Страниц (2): [1] 2 »
 

1. Ch_chov - 06 Июня, 2009 - 16:02:16 - перейти к сообщению
Есть скрипт каталога товаров с базой данных примерно следующей структуры:

Id (ид товара)
name (наименование)
desc (описание)
rating (рэйтинг)

Рэйтинг соответствует количеству просмотров данного товара за всё время. Т.е. при каждом клике на изображение товара, рейтинг увеличивается на единицу.

Добавил в таблицу дополнительные поля:
r_1 (количество просмотров за последний месяц)
r_2 (количество просмотров за последние 6 месяцев)
r_3 (количество просмотров за последний год)

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

Кто нибудь решал подобную задачу?
2. ALEN - 06 Июня, 2009 - 16:41:24 - перейти к сообщению
Можно просто создать таблицу:
id
id-товара
ye - год
me - месяц
de - день
h - час
i - минуты
s - секунды

При просмотре добавляем запись в таблицу со всеми данными и при выводе просто считаем, солько записей по условию, так можно сделать рейтинг за час...
3. EuGen - 06 Июня, 2009 - 16:46:43 - перейти к сообщению
Думаю, что придется хранить данные по месяцам, как Вы и предположили. В таких случаях приходится создавать таблицу с данными, делая шаг в минимальный по протяженности отрезок времени (то есть, как у Вас - 1 месяц).
4. ALEN - 06 Июня, 2009 - 16:49:11 - перейти к сообщению
EuGen
А чем мой вариант не подходит, чтоб можно было вообще, в любой момент изменить условия вывода рейтинга?
5. EuGen - 06 Июня, 2009 - 16:55:54 - перейти к сообщению
Тем, что Ваш вариант по сути, можно и правильнее сделать так: создать таблицу, куда записывать только одно поле - дату клика (вместе со временем). А при выводе пользователю считать COUNT по этой таблице. Конечно, такое построение даст возможность считать рейтинг за любой промежуток времени.
Но. Представьте себе, что у нас хотя бы 100000 кликов в день.. Это будет 36500000 записей за год. И самое главное, что нет ни одного поля, по которому бы можно было создать индекс (поле по сути одно и оно индекс по нему будет иметь слишком высокое значение CARDINALITY). И если мы захотим выбрать COUNT из такой таблицы, это приведет к жутко тормозному FULL SCAN (так как нет индексов).
Поэтому лучше хранить данные в уже агрегированном виде, когда достаточно знать число посещений за месяц. Правда, в этом случае мы будем знать число посещений именно за календарный, а не астрономический, месяц. (То есть если сейчас, к примеру, 6-е число, то мы не сможем узнать число посещений с 6-го мая по 6-е июня, а только с 1-го мая по 1-е июня).
6. Ch_chov - 06 Июня, 2009 - 17:42:46 - перейти к сообщению
Цитата:
Можно просто создать таблицу:
id
id-товара
ye - год
me - месяц
de - день
h - час
i - минуты
s - секунды

Тогда может проще будет сделать
Id – ид товара
timestamp – дата просмотра

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

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

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


Про каленадрные периоды тоже думал. В принципе это устраивает. Т.е. когда пользователь кликает на ссылку "лучшие товары за 3 месяца", он получит выброку лучших товаров за 3 предыдущих месяца, без учёта текущего. Например, если сегодна 6-е июня, то выборка будет произведена за период с 1-е марта по 31 мая.

Сейчас вот думаю, може быть лучше привести таблицу к следующему виду:
Id (ид товара)
name (наименование)
desc (описание)
rating (рейтинг)
rm_1 (количество просмотров за январь)
rm_2 (количество просмотров за февраль)
rm_3 (количество просмотров за март)
...
rm_12 (количество просмотров за декабрь)

Тогда для того что бы выбрать лучшие товары за 3 месяца запрос будет выглядеть следующим образом
CODE (text):
скопировать код в буфер обмена
  1.  SELECT * FROM `tableName` ORDER BY `rm_5` + `rm_4` + `rm_3`

Интересно, как это по влияет на производительность? Ведь если делать выборку за год, то надо будет суммировать значения 12-ти поле.
И вообще, само по себе увеличение количества полей в таблице тоже наверно не очень хорошо?
7. EuGen - 06 Июня, 2009 - 17:50:39 - перейти к сообщению
Увеличение числа полей ничем не плохо для СУБД, но для чтения человеком излишнее может быть вредно. Хотя в данном случае, не думаю, что это так. Альтернативой можно посоветовать отдельную таблицу. То есть id товара, номер месяца, рейтинг в этом месяце. Правда, тогда уже агрегация данных будет выполняться несколько дольше (нужно будет суммировать данные из присоединяемой таблицы)
Суммирование - простая арифметическая операция, так что это точно не приведет к падению производительности.
Чем плохо записывать таймштамп каждого клика - я, кажется, уже объяснил.
8. ALEN - 06 Июня, 2009 - 17:51:56 - перейти к сообщению
EuGen
Дык при таких нагрузках, можно снизить точность до одного дня, т.е. получится в год примерно 365 записей в таблице! А мы сможем вычислить с 6-го мая по 6-е июня спокойно количество посещений или кликов, и то и другое можно записывать туда же.
Если делать с точностью до одного часа, то выйдет примерно 8760 записей в год. Думаю такая четкость и нагрузка довольна хороша! Тем более, что можно организовать кэширование на вычисление периодов больших чем за месяц.
9. EuGen - 06 Июня, 2009 - 17:54:39 - перейти к сообщению
То есть в итоге, все сводится к агрегируемой таблице, как я и описал. Только Вы сейчас предлагаете сделать интервал, равный 1 дню. А идейно разницы нет никакой.
10. ALEN - 06 Июня, 2009 - 17:58:18 - перейти к сообщению
EuGen Тут любой вариант - это дело точности вывода данных, даже мой первый вариант можно оптимизировать и давать с точность до секунды результат!

Да и поправка - "с точность до часа" - можно спокойно организовывать!!! Выйдет только 8760 в год примерно.
11. EuGen - 06 Июня, 2009 - 18:24:43 - перейти к сообщению
И как Вы будете оптимизировать вариант "с точностью до секунды?"
Приведите, пожалуйста, аргументы, почему Ваш вариант лучше. Пока что я вижу лишь большое число восклицательных знаков. К тому же в последнем случае, повторюсь, идейно нет никакой разницы.
12. ALEN - 06 Июня, 2009 - 18:32:59 - перейти к сообщению
EuGen
1) А зачем вычислять постоянно колличество?
2) Вариант с точностью до часа - я бы делал именно его, записей в год получается не много, а точность вывода можно организовать до часа. Я считаю самый оптимальный вариант.
13. EuGen - 06 Июня, 2009 - 18:44:06 - перейти к сообщению
1) Если делать "с точностью до секунды" - предложите вариант, как Вы будете вычислять
2) С точностью до часа - второй раз повторюсь, это такое же точно агрегирование. Автору темы было нужно с точностью до месяца, и поэтому был предложен наибольший интервал - месяц.
Наше с Вами обсуждение уже ушло в сторону от темы, я полагаю.
14. ALEN - 06 Июня, 2009 - 19:01:25 - перейти к сообщению
EuGen
Не вижу смысла делать с точностью до секунды, тогда лучше подсчитывать количество уникальных кликов.
А вот вариант с Вашими месяцами, лучше записывать с точностью до дня, чтоб можно было выводить в середине месяца не за 15 дней, а точно за 30 или 31 день.
Т.к. тогда за последний месяц если, как Вы говорите 100 000 кликов в стуки, то в месяц их примерно 3 000 000 , а посетитель увидит например в первый день 100 000 и тогда по статистике будут очень сильные скачки.

Только представьте, что 30 числа пользователь видит 3 000 000 скачиваний, а через день - два - уже 100 000
15. EuGen - 06 Июня, 2009 - 19:24:38 - перейти к сообщению
Так ведь не я посоветовал делать с точностью до секунды, а календарные периоды вполне устраивают автора.
P.S. Я правда не понимаю, о чем речь и спор.

 

Powered by ExBB FM 1.0 RC1