Реализация статистики просмотров

Oops

Новичок
Реализация статистики просмотров

Необходимо реализовать следующее: пользователь просматривает какую-то страницу с каким-то товаром (например) и он может внизу посмотреть с какими товарами покупают текущий.

Для примера: http://www.ozon.ru/context/detail/id/3937683/ (внизу: "С этим товаром часто покупают", "Те, кто смотрел эту страницу, затем купили").

Лично мне это необходимо не для интернет-магазина, но суть та же.

Мне интересен не просто способ подобной реализации, а оптимальный способ. Как Вы бы сделали такое? Просто на словах.
 

Alexandre

PHPПенсионер
хранятся все оплаченные карзины,
далее делается выборка по карзинам, в которой есть заданый товар.
все эти записи выводятся, кроме заданной. а лучше сделать group by count(*)
и вывести три наиболее покупаемых...

в результате получаем, что вместе с покупкой книги "Александреску. Стандарты программирования" натболее часто покупают "Учебник шахматной игры для школьников", (books.ru)
очевидно, я был единственный кто купил эту книгу в паре с учебником шахматной игры :)
 

MiksIr

miksir@home:~$
Поскольку все же покупка гораздо реже просмотров, лучше вести отдельную таблицу, удобную для выборки и апдейтить ее при покупке.
Например, id_книги_1, id_книги_2, count
Правда, на каждую покупку тогда потребуется (n-1)*n апдейтов.
Если вести выборку не только по первому полю, но и по второму через OR, то выборка будет чуток потяжелее, но апдейтов нужно будет в два раза меньше.
 

dimagolov

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

а аплейт то будет одним запросом:
update ref_count set pair_count = pair_count + 1 where id1 = curId or id2 = curId

ну а id1 & id2 свести в составной уникальный ключ, по которому и будет исполняться запрос. не очень хорошо то, что pair_count тоже по логике надо индексировать. Кто в курсе, индекс при таком update будет перестраиваться каждый раз, или один - после отработки запроса?
 

MiksIr

miksir@home:~$
Индекс тут не составной, а два отдельных уникальных, тогда уж, ибо OR.
Угу, тогда экономим на количестве запросов - нужно их n... вернее 2n ибо все ж OR придется выбросить, так как нам новые вхождения все же как-то нужно инициализировать... не строить же заранее матрицу N*N, где N - кол-во товаров вообще. А вот теряем на скорости апдейта, ибо нужно апдейтить весь ряд(столбец) матрицы, а не одну ячейку.

-~{}~ 06.08.08 19:40:

Э.. не, все хренотень, не будет так работать.
 

dimagolov

Новичок
почему не составной? храним то элемент матрицы, то есть пары ij (i= id1, j= id2) (i!=j). кроме того, матрица симметрична будет, то есть храним ее половину (i > j). Ну а раз элемент матрицы один, то пара ij будет в таблице не более одного раза, и то не все, то есть составной уникальный индекс i,j хоть и не покрывает всех ограничений, но и не усиливает их.
при каждом добавлении нового товара надо будет вставлять ко-во записей, равное предидущему кол-ву товаров вида (newId, oldId_k, 0)

ни и отбирать нужные значения по id1 = curId or id2 = curId, как и при обновлении
 

Oops

Новичок
Вообще я не покупки, а по просмотрам веду статистику. Если вам интересна развязка моей проблемы, то я сделал так:
Код:
INSERT INTO ... (`id1`, `id2`, ...) VALUES(1, 2, ...) ON DUPLICATE KEY UPDATE `q` = `q` + 1;
where id1 = curId or id2 = curId
Чтобы не создавать такие условия, у меня левый id всегда меньше правого.

Поставил уникальный ключ на левый, правый id и день через TO_DAYS(NOW()), потом каждая запись будет удаляться через неделю. В итоге у меня получилась статистика просмотров товара с другими за последнюю неделю.

Если кто-то видит изъяны в подобной реализации - просьба написать.
 

MiksIr

miksir@home:~$
Oops, сори, мы тут о своем пообщаемся ;)
dimagolov, не составной, ибо при составном ключе (id1, id2) на выборку/апдейт по полю id2 этот индекс не будет работать.
А насчет id1 = curId or id2 = curId - проиллюстрируйте, что будет обновляться и как нам потом из этого выбрать зависимость товаров. У меня вот получается, что если для каждого товара из корзины мы будем делать for ($items as $item) "UPDATE .. WHERE id1=$item->id OR id2=$item->id"; то получается полная хренатень, ибо где тут взаимосвязь товаров то?
 

dimagolov

Новичок
как по мне изъян в том, что надо делать N insert-ов (вместо одного update при просмотре и N insert при добавлении новых товаров) всегда, причем предварительно отбирать существующие id.

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

Только не понимаю идеи удаления - типа если новых просмотров не было неделю, то удаляем, и начинаем считать с 0, а если каждые 6 дней просмотр был, то счетчик ростет бесконечно. Куда логичнее делать "снимки" состояния таблицы каждую неделю и после этого отнимать от текущего значения значение недельной давности, чтобы держать статистику только за последнюю неделю.

Я бы попробовал и ту и другую реализации и потестил бы на более или менее реалистичном кол-ве товаров.

-~{}~ 06.08.08 14:21:

не составной, ибо при составном ключе (id1, id2) на выборку/апдейт по полю id2 этот индекс не будет работать.
что-то не уверен, ща буду проверять в живую

получается полная хренатень
точно, это я протормозил, у нас всегда при обновлении пара имеется. а почему ступил я понял. я пытался транзитивность реализовать, что может иметь (а может и не иметь) смысл
 
Сверху