2009-06-22 32 views
12

Estoy creando un sitio web digg que tendrá una página de inicio con diferentes categorías. Quiero mostrar los envíos más populares.Algoritmo de Popularidad

Nuestro sistema de clasificación es simplemente "me gusta", como "me gusta esto" y otras cosas. Básicamente, queremos mostrar los envíos con el mayor número de "me gusta" por hora. Queremos tener tres categorías: popularidad de todos los tiempos, la semana pasada y el último día.

¿Alguien sabe de alguna manera de ayudar? No tengo idea de cómo hacer esto y hacerlo eficiente. Pensé que podríamos usar algún tipo de cron-job para ejecutar cada 10 minutos y obtener la cantidad de me gusta en los últimos 10 minutos ... ¿pero me han dicho que es bastante ineficiente?

¿Ayuda?

Gracias!

Respuesta

9

Por lo general, los sitios Digg y Reddit se ajustan a la fecha de envío y no a los tiempos de los votos. De esta forma, todo lo que se necesita es una simple consulta SQL para encontrar los mejores envíos para el período X. Aquí hay un pseudo-consulta para encontrar los 10 enlaces más populares de las últimas 24 horas usando este método:

select * from submissions 
where (current_time - post_time) < 86400 
order by score desc limit 10 

Básicamente, esta consulta dice que encontrar todas las presentaciones, donde el número de segundos entre el momento actual y el momento en que se publicado es menor que 86400, que es 24 horas en tiempo UNIX.

Si realmente se quiere medir popularidad dentro de intervalo de tiempo X, que necesita para almacenar el mensaje y la hora por cada voto en otra tabla:

create table votes (
post foreign key references submissions(id), 
time datetime, 
vote integer); -- +1 for upvote, -1 for downvote 

A continuación, se puede generar una lista de los más populares puestos entre X e y veces de esta manera:

select sum(vote), post from votes 
where X < time and time < Y 
group by post 
order by sum(vote) desc limit 10; 

desde aquí no eres más que un salto, salto, y se unen interior lejos de conseguir los datos de envío atadas a los identificadores devueltos.

+1

Escribía básicamente lo mismo, eras más rápido que yo. =) –

+1

excelente respuesta ... parece que aunque el primer método que describes es más simple, no maneja el caso donde algo que se publicó hace un tiempo atrás vio un repentino resurgimiento de popularidad (tal vez debido a un evento noticioso reciente o alguna cosa)? el segundo método parece más robusto, ¡gracias lo probaré! –

-1

Para completar la respuesta de nadie, le sugiero que lea en el documentation (si está utilizando MySQL, por supuesto).

3

¿Tiene una configuración de base de datos decente? ¿Podemos saber acerca de sus detalles CREATE TABLE e índices? ¡Suponiendo una configuración sensata, la base de datos debería ser capaz de extraer los conteos que necesita con la rapidez suficiente para satisfacer sus necesidades! Por ejemplo (netos de los índices y llaves, que tanto dependen de qué motor de base de datos que está utilizando), dados dos tablas:

CREATE TABLE submissions (subid INT, when DATETIME, etc etc) 
CREATE TABLE likes (subid INT, when DATETIME, etc etc) 

puede obtener los mejores presentaciones populares de todos los tiempos 33 como

SELECT *, COUNT(likes.subid) AS score 
FROM submissions 
JOIN likes USING(subid) 
GROUP BY submissions.subid 
ORDER BY COUNT(likes.subid) DESC 
LIMIT 33 

y los que votaron por dentro de un cierto rango de tiempo como

SELECT *, COUNT(likes.subid) AS score 
FROM submissions 
JOIN likes USING(subid) 
WHERE likes.when BETWEEN initial_time AND final_time 
GROUP BY submissions.subid 
ORDER BY COUNT(likes.subid) DESC 
LIMIT 33 

Si estaba almacenando "votos" (positivos o negativos) en likes, en lugar de contar cada entrada allí +1, podría simplemente usar SUM(likes.vote) en lugar de COUNT s.

0

Para una lista estable como de todos los tiempos, de la última semana, porque se supone que no deben cambiar muy rápido, así que creo que debes guardar la lista en tu caché con un tiempo de expiración de alrededor de 1 día o más.

Si le preocupa el recuento correcto en tiempo real, puede verificar en cada vista de página comparando la página con la página más baja en la caché.

Todo lo que necesita hacer es cuidar la sincronización entre el caché y la base de datos real.

thethanghn

+0

el objetivo de mi enfoque es reducir la mayor consulta de base de datos posible, ya que no es necesario obtener la parte superior de la base de datos todo el tiempo – thethanghn

0

consultas donde el orden es una función de la hora actual puede convertirse en problemas de rendimiento real. Las cosas se vuelven mucho más simples si puedes cambiar el tiempo por calendario y actualizar los puntajes de cada categoría a medida que la gente vota.

Cuestiones relacionadas