[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Алгоритм для вывода топ N записей
Gesandte
//Парни, помогите пожалуйста с алгоритмом, а то хрень в голове верититься.

Пример.
Необходимо вывести 5 самых популярных новостей за последнюю неделю.

Вначале была идея следующая
------------------------------------------------------
page | count
------------------------------------------------------
news1 | 7
------------------------------------------------------
news2 | 35
------------------------------------------------------
news3 | 12
------------------------------------------------------

Т.е при каждом уникальном посещении страницы, мы ищеем ее в БД и делаем +1 в графе count. Но так не получается определить популярность за период времени, только с самого начала добавления записи.

Сейчас думаю так
-----------------------------------------------------
page | date
-----------------------------------------------------
news1 |
-----------------------------------------------------
news2 |
-----------------------------------------------------
news1 |
-----------------------------------------------------
news1 |
-----------------------------------------------------
news3 |
-----------------------------------------------------

При каждом уникальном посещении добавлять страницы в БД с указанием времени.
Позже считать при помощи WHERE в sql.......но получается надо подсчитать кол-во всех уникальных страниц в базе, а потом уже выводить записи, с max повторением....
Хреновый алгоритм.....

Как быть?



Спустя 3 минуты, 53 секунды (23.08.2012 - 19:55) johniek_comp написал(а):
order by count desc


и все...

Спустя 2 минуты, 7 секунд (23.08.2012 - 19:57) inpost написал(а):
Что значит "за последнюю неделю".
Допустим сегодня среда, как неделю считать будем?

johniek_comp
За последнюю неделю, не за весь период!

Спустя 39 секунд (23.08.2012 - 19:57) johniek_comp написал(а):
а стоп
да, нужно писать время и тогда запрос будет примерно таким
select * from table
where

date >= adddate(now(), interval - 7 day)
order by count
desc

Спустя 1 минута, 27 секунд (23.08.2012 - 19:59) inpost написал(а):
johniek_comp
Ты опять не понял. Популярна за последнюю неделю, а не за весь период. То есть в прошлой неделе 20 заходов, в этой 10, считаем именно не 30, а 10(!).

Спустя 10 минут, 39 секунд (23.08.2012 - 20:09) Gesandte написал(а):
ну да, либо сразу в запросе отсекать, либо брать не ровно неделю, а с небольшой погрешностью, кроном запускать скрипт например каждый день или 12 часов и удалять старые записи, тогда считаем по всем.....

пойду пример сделаю....виртуально туго думается)

Спустя 5 минут, 36 секунд (23.08.2012 - 20:15) johniek_comp написал(а):
inpost
тогда нужно завести доп. табличку где хранить id новости и время когда был этот +1 в count поле, таблицы какой-то там

select *, count(t.id)
from
table
,table1 as t
where t.date_create
between
'дата понедельника' and 'дата пятницы'
and
t.id_news = 10


по идее вернет сколько заходов было за выбранный промежуток для новости с id = 10, хотя могу ошибаться

Спустя 21 минута, 15 секунд (23.08.2012 - 20:36) Gesandte написал(а):
Цитата (johniek_comp @ 23.08.2012 - 18:15)
по идее вернет сколько заходов было за выбранный промежуток для новости с id = 10, хотя могу ошибаться

johniek_comp, со sql у меня туго...но получается что здесь мы определяем кол-во запросов за период времени по конкретной записи....

А если у нас уникальных записей сотня...то тогда надо высчитать кол-во просмотров по каждой из них, а потом делаем вывод из этого массива данных с max кол-ом просмотров, которые мы вычислили ранее. Помоему такой способ окажется весьма нагрузочным....

Спустя 4 минуты, 15 секунд (23.08.2012 - 20:41) inpost написал(а):
johniek_comp
Тут всё зависит от моего вопроса, если неделя (7 последних дней), то отдельная таблица. Если неделя идёт с понедельника по понедельник, то можно count обновлять 1 раз в неделю и всё кроном.

Спустя 1 минута, 57 секунд (23.08.2012 - 20:43) inpost написал(а):
Я это не спроста спросил в начале. Под каждую задачу надо искать наиболее оптимальное решение. В этом и заключается работа Mysql-архитектора, даже целая отдельная профессия smile.gif

Спустя 1 минута, 36 секунд (23.08.2012 - 20:44) Gesandte написал(а):
inpost , первый вариант. скользящее время

Спустя 5 минут, 47 секунд (23.08.2012 - 20:50) johniek_comp написал(а):
inpost
мой вариант вполне рабочий, не надо никаких cronov и т.д. и гибкий, можно посмотреть сколько было заходов хоть с 10-ти до 11-ти утра нужного дня smile.gif

Gesandte
это не нагрузочно, мы же php не дергаем, mysql на это и рассчитано на миллионы записей и т.д. и на работу с ними

Спустя 22 минуты, 15 секунд (23.08.2012 - 21:12) Gesandte написал(а):
johniek_comp, но нам же придется делать сотню запросов к БД, т.е все это прогонять через цикл и писать нужные нам данные в некий массив. После выдернуть как то энное кол-во записей с максимальным показателем....функция max не пойдет. А перед всем этим надо узнать все уникальные имена страниц в базе, которые будут содержаться в массиве и который нам и предстоит изначально прогнать.......

# Как то получаем уникальные имена страниц, содержащиееся в базе, получаем нечто ....
$pages = array('news1', 'news2', ... , 'newsN');

foreach ($pages as $uid) {
$sql_count = mysq_query("
select *, count(t.id)
from
table,table1 as t
where t.date_create
between
'дата понедельника' and 'дата пятницы'
and
t.id_news =
$uid");

# В верности это йзаписи сомневаюсь....)) но смыс ясен
$count[] = array($uid, $sql_count);
}


дальше каким то образом расскладываем массив $count....так получается?
как то круто выходит.......

Спустя 5 минут, 24 секунды (23.08.2012 - 21:18) Gesandte написал(а):
можно сделать конечно кэширование работы этого скрипта, и перезапускать его каждый час к примеру, для обновления результатов, а все остальное время отдавать html......

Спустя 19 минут, 39 секунд (23.08.2012 - 21:37) sergeiss написал(а):
Цитата (Gesandte @ 23.08.2012 - 21:51)
Необходимо вывести 5 самых популярных новостей за последнюю неделю.

Вопрос: сколько всего записей в таблице новостей? Это важно, т.к. при небольшом количестве записей не надо никаких кэширований и отдельных таблиц, т.е. алгоритмы могут быть разные для малого и большого количества. А критерий "малости" тоже понятие весьма относительное, вобщем-то smile.gif

Спустя 1 минута, 27 секунд (23.08.2012 - 21:39) inpost написал(а):
Gesandte
Ты бы на мой вопрос ответил бы smile.gif И добавил, есть ли нечто вроде "за месяц", "за всё время"?

Спустя 19 минут, 2 секунды (23.08.2012 - 21:58) Gesandte написал(а):
sergeiss , сейчас мало, сайт только запускаю, может около 40, ну а через год их там может быть и под тысячу....

Спустя 3 минуты, 33 секунды (23.08.2012 - 22:01) Gesandte написал(а):
Цитата (inpost @ 23.08.2012 - 19:39)
Gesandte
Ты бы на мой вопрос ответил бы smile.gif И добавил, есть ли нечто вроде "за месяц", "за всё время"?

inpost, так я вроде ответил)
За последнее N-кол-во дней.

пример. за неделю.
сегодня четверг 23.00, значит с четверга 23.00 (16.08.2012) по четверг 23.00 (23.08.2012), завтра пятница, значит с пятницы по пятницу и тд

Спустя 2 часа, 6 минут, 46 секунд (24.08.2012 - 00:08) inpost написал(а):
Gesandte
Отдельная таблица с кликами, собирай клики за сутки в одной записи к одной новости. Новостей хоть не очень много?!
Далее делаешь выборку по дате из второй таблицы, сортируешь по COUNT(*), GROUP BY `news_id`, и ставишь LIMIT 10, получаешь 10 новостей, у которых наибольшее число счётчика. Далее запрос №2, выборка из первой таблицы самой новости!
Индексы расставь, пока миллионов записей не будет, всё будет ок. У меня проблемы начинаются с 18млн., при этом хостинг загружен ещё видео-сервером и многим другим.

Спустя 12 часов, 12 минут, 5 секунд (24.08.2012 - 12:20) Gesandte написал(а):
inpost, с утра уже думаю...но так и не пойму как соеденены таблицы с кликами за сутки, с таблицей где указаны даты................

Спустя 2 часа, 5 минут, 30 секунд (24.08.2012 - 14:26) Gesandte написал(а):
Это на правду похоже?


Таблица уникальных страниц, просмотренных за последнюю неделю
uniquePage
+-------------+------------------+
|
id | page |
+-------------+------------------+
|
1 | news1 |
+-------------+------------------+
|
2 | news2 |
+-------------+------------------+
|
3 | news3 |
+-------------+------------------+
|
4 | news4 |
+-------------+------------------+
|
5 | news5 |
+-------------+------------------+



Таблица посещений
visitPage
+------------------+-------------+
|
page | date |
+------------------+-------------+
|
news1 | timestamp |
+------------------+-------------+
|
news2 | timestamp |
+------------------+-------------+
|
news2 | timestamp |
+------------------+-------------+
|
news1 | timestamp |
+------------------+-------------+
|
news3 | timestamp |
+------------------+-------------+
... ...
+------------------+-------------+
|
news3 | timestamp |
+------------------+-------------+
|
news5 | timestamp |
+------------------+-------------+



<?php

$popularPage = array();

$queryUniquePage = mysql_query("SELECT * FROM `uniquePage`");

if (mysql_num_rows($queryUniquePage)) {
while ($uniquePage = mysql_fetch_array($queryUniquePage)) {
$queryCount = mysql_query("SELECT COUNT(*) FROM `visitPage` WHERE page = $uniquePage[$page] AND date >= ADDDATE(now(), interval - 7 DAY)");
$count = mysql_fetch_array($queryCount);

# Пишем в массив
$popularPage[$page] = $count;
}
}


# Вытаскиваем топ-N из массива
# Делаем запросы для получения новости


?>
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.