2008-11-01 11 views
4

Sur my blog, j'affiche dans la navigation de droite les 10 articles les plus populaires en termes de hits de pages. Voilà comment je reçois que:Quel est le meilleur moyen de calculer les hits de pages par jour dans MySQL?

SELECT * 
FROM entries 
WHERE is_published = 1 
ORDER BY hits DESC, created DESC 
LIMIT 10 

Ce que je voudrais faire est de montrer le top 10 en termes de la page par jour frappe. J'utilise MySQL. Y a-t-il un moyen de le faire dans la base de données? Le champ created est un datetime.

MISE À JOUR: Je pense que je n'ai pas été clair. Ce que je veux, c'est pour le billet de blog avec 10.000 visites publiées il y a 1.000 jours pour avoir la même popularité que l'article de blog avec 10 réponses publiées il y a 1 jour. En pseudo-code:

ORDER BY hits/days since posting 

... où hits est juste un entier qui est incrémenté à chaque fois que le message de blog est affiché.

OK, voici ce que je vais utiliser:

SELECT *, AVG(
    hits/DATEDIFF(NOW(), created) 
) AS avg_hits 
FROM entries 
WHERE is_published = 1 
GROUP BY id 
ORDER BY avg_hits DESC, hits DESC, created DESC 
LIMIT 10 

Merci, Stephen! (J'aime ce site ...)

Répondre

6

Je ne suis pas entièrement sûr que vous pouvez en utilisant la structure de table que vous suggérez dans votre requête. La seule façon que je peux penser est d'obtenir le top 10 par le moyen moyen hits par jour. En faisant cela, votre requête devient:

SELECT *, AVG(hits/DATEDIFF(NOW(), created)) as avg_hits 
FROM entries 
WHERE is_published = 1 
GROUP BY id 
ORDER BY avg_hits DESC 
LIMIT 10 

Cette requête suppose que votre champ créé est d'un DATETIME (ou similaire) type de données.

+0

C'est la bonne idée, mais ne voudrais-je pas ORDER BY avg_hits? –

+0

Ouais, j'ai eu environ 5 réponses dans les 5 dernières minutes et je semble continuer à oublier des choses ... –

+0

Il y a une faute de frappe dans votre requête, btw. Vous avez besoin d'un autre parent de clôture dans le select. –

1

Je suppose que vous pourriez avoir une colonne hits_day_count, qui est incrémentée sur chaque vue, et un hits_day_current.

Dans chaque page-vue, vous vérifiez si la colonne hits_day_current est aujourd'hui. Si ce n'est pas le cas, réinitialisez le nombre de hits. Ensuite, vous incrémentez la colonne hits_day_count et définissez hits_day_current sur le datetime actuel.

Pseudo-code:

if article_data['hits_day_current'] == datetime.now(): 
    article_data['hits_day_count'] ++ 
else: 
    article_data['hits_day'] = 0 

article_data['hits_day_current'] = datetime.now() 

Le problème évident avec c'est simple - timezones. Les totaux sont réinitialisés à 00:00 partout où se trouve le serveur, ce qui peut ne pas être utile.

Une meilleure solution serait un total de roulement de 24 heures .. Pas tout à fait sûr comment le faire proprement. Le moyen le plus simple (mais pas si élégant) serait d'analyser périodiquement les journaux de votre serveur Web. Obtenez les dernières 24 heures de journaux, comptez le nombre de demandes pour chaque article et mettez ces nombres dans la base de données.

+0

Pour faire ce que vous suggérez mieux serait fait par une autre langue de concert avec MySQL. Avoir un champ supplémentaire (hits_day) qui représente le jour des hits. Lors de l'ajout à la base de données, vérifiez d'abord si ce jour est aujourd'hui. Si oui, +1. Si ce n'est pas le cas, réinitialisez à 1 et rendez hits_day égal à aujourd'hui. –

+0

La seule raison pour laquelle je prendrais cette approche serait la performance. Je pourrais exécuter un travail cron pour calculer la popularité tous les soirs, puis je suis de retour à un simple SELECT. Pour mes fins, cependant, c'est bien juste de calculer cela à la volée. –