2010-11-15 6 views
8

Je travaille pas un site qui stocke des vues individuelles de page dans une table « vues »:La meilleure façon de stocker vues/stats dans MySQL

CREATE TABLE `views` (
    `view_id` bigint(16) NOT NULL auto_increment, 
    `user_id` int(10) NOT NULL, 
    `user_ip` varchar(15) NOT NULL, 
    `view_url` varchar(255) NOT NULL, 
    `view_referrer` varchar(255) NOT NULL, 
    `view_date` date NOT NULL, 
    `view_created` int(10) NOT NULL, 
    PRIMARY KEY (`view_id`), 
    KEY `view_url` (`view_url`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 

Il est assez basique, de magasins (id de l'utilisateur sur la site), leur adresse IP, l'url (sans le domaine pour réduire la taille de la table un peu), l'URL de référence (n'utilisant pas vraiment cela en ce moment et pourrait s'en débarrasser), la date (AAAA-MM-JJ format bien sûr), et l'horodatage unix de quand la vue s'est produite.

La table, bien sûr, devient assez grande (4 millions de lignes pour le moment et c'est un site plutôt jeune) et les requêtes en cours sont lentes.

Pour une optimisation de base que j'ai créé une table « views_archive »:

CREATE TABLE `views_archive` (
    `archive_id` bigint(16) NOT NULL auto_increment, 
    `view_url` varchar(255) NOT NULL, 
    `view_count` smallint(5) NOT NULL, 
    `view_date` date NOT NULL, 
    PRIMARY KEY (`archive_id`), 
    KEY `view_url` (`view_url`), 
    KEY `view_date` (`view_date`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 

Cela ne tient pas les informations de l'utilisateur (et l'URL de référence) et stocke combien de fois url a été vu par jour. C'est probablement la manière dont nous allons généralement utiliser les données (combien de fois une page a été consultée par jour), donc l'interrogation devrait être assez rapide, mais même si je l'utilise pour remplacer principalement la table 'views' (à droite maintenant j'imagine que je pourrais montrer des pages vues par heure pour la dernière semaine/mois ou alors et montrer les vues journalières au delà de cela et ainsi seulement besoin de la table 'views' pour contenir les données de la dernière semaine/mois) mais c'est quand même table. Quoi qu'il en soit, histoire courte, je me demande si vous pouvez me donner des conseils sur la meilleure façon de gérer le stockage de statistiques/pages vues dans un site MySQL, le but étant à la fois de garder la taille de la table (s) dans le db aussi petit que possible et toujours être en mesure de facilement (et au moins relativement rapidement) interroger l'info. J'ai regardé un peu les tables partitionnées, mais MySQL 5.1 n'est pas installé sur le site. Tous les autres conseils ou idées que vous pourriez offrir seraient très appréciés.

+0

umm, doesn Est-ce que votre serveur a un journal d'accès qui garde déjà toutes ces données? Il y a beaucoup de visionneuses/résumés de journaux là-bas pour les journaux d'accès Web. Y a-t-il une raison impérieuse de ne pas en utiliser une? – dnagirl

+0

Quel est le but de la colonne view_created? –

+0

Le but de la colonne view_created, MicWafflestix, serait utilisé si je voulais afficher les vues toutes les heures (disons combien de fois un article était vu chaque heure aujourd'hui). Je suppose que je pourrais utiliser DATETIME au lieu de l'horodatage INT (10), mais je ne suis pas sûr que cela m'aiderait beaucoup. – Charlie

Répondre

1

Vous souhaitez probablement avoir une table uniquement pour les pages et que les vues utilisateur contiennent une référence à cette table. Une autre optimisation possible serait d'avoir l'adresse IP de l'utilisateur stockée dans une table différente, peut-être certaines informations de la table de session. Cela devrait réduire vos temps de requête quelque peu. Vous êtes sur la bonne voie avec la table d'archivage; les mêmes optimisations devraient aider cela aussi.

+0

J'aime cette idée. On dirait que c'est une bonne base d'optimisation solide de la structure des données (par opposition à la mise à niveau de mysql ou à l'utilisation d'une table nosql ou d'un autre gros changement que je craignais d'avoir à faire). Je viens aussi de découvrir la fonction INET_ATON() dans MySQL qui pourrait m'aider à réduire la taille de stockage de l'adresse IP (on peut utiliser INT au lieu de VARCHAR). Pour le court terme, de toute façon, je pense que les solutions que vous avez mentionnées contribueront grandement à régler mes problèmes. Merci. – Charlie

+0

@Charlie: de rien. À grande échelle, les petites optimisations commencent vraiment à faire une grande différence; en même temps, certaines des optimisations vraiment complexes ne donnent tout simplement pas le rendement attendu. Je trouve que les optimisations simples et directes sont généralement ce qui m'amène à 90% du chemin vers une bonne solution, sinon tout le chemin. –

1

Archive MySQL Storage Engine

http://dev.mysql.com/tech-resources/articles/storage-engine.html

Il est idéal pour les journaux, il est rapide à écrire, le seul inconvénient est en train de lire est un peu plus lent. mais c'est génial pour les tables de journaux.

+0

J'ai regardé ça un peu l'autre jour. Cela semble intéressant, mais ce n'est pas "pris en charge" (vérifié via SHOW ENGINES, query) sur mon installation actuelle de MySQL. Je vais demander aux personnes qui l'hébergent de l'allumer ou de le faire et de jouer avec. Merci pour le conseil. – Charlie

+0

Le lien est cassé. –

0

En supposant que votre application est un blog et que vous souhaitez garder une trace des vues pour vos billets de blog, vous aurez probablement une table appelée blog_posts. Dans cette table, je vous suggère de créer une colonne appelée "vues" et dans cette colonne, vous stockez une valeur statique du nombre de vues que ce post a. Vous utiliserez toujours la table views, mais celle-ci ne sera utilisée que pour garder une trace de toutes les vues (et faire des vérifications si elles sont "uniques" ou non).

Fondamentalement, quand un utilisateur visite un billet de blog, il va vérifier la table views pour voir si elle devrait être ajoutée. Si c'est le cas, le champ "views" sera également incrémenté dans la ligne correspondante pour le blog dans blog_posts. De cette façon, vous pouvez simplement vous référer au champ "vues" pour chaque article pour avoir un aperçu rapide du nombre de vues qu'il a. Vous pouvez aller plus loin et ajouter de la redondance en configurant un travail CRON pour recompter et vérifier toutes les vues et mettre à jour chaque ligne blog_posts en conséquence à la fin de la journée.Ou si vous préférez, vous pouvez également effectuer un nouveau compte sur chaque mise à jour si la précision à la seconde est clé.

Cette solution fonctionne bien si votre site est en lecture intensive et que vous rencontrez en permanence pour obtenir un compte de nombre de vues de chaque billet de blog a (encore une fois, en supposant que est votre :-) d'application)

Questions connexes