Vérifier l'état d'une table Mysql

Voila je suis en train de développer une solution de cache PHP. Seulement le PHP c’est dynamique donc ca tiens compte d’un tas de variables. Alors je suis malin comme un singe, j’ai fait des concaténations dans tous les sens pour vérifier que l’état de la page en cache est bien le meme que la page demandée (même cookies, même paramètres en ligne de commande, etc…).

Seulement voila! Pas moyen de tester l’état de dernière modification d’une table MySQL. En gros j’aimerais savoir quand la table a subit des modification, (par exemple la derniere date a la seconde près) pour que je puisse évaluer si mon cache est encore valide.

Il est bien entendu exclus que je fasse les même requetes que dans le PHP de base (sinon ca sert a rien de servir le cache autant recalculer la page). LAST_INSERT_ID est exclus aussi, car il n’est pas garantit que la table possède un champ auto increment. Exclus aussi de se baser sur un champ TIMESTAMP, rien dans la table ne garantissant que ce champ existe.

La seule solution que j’ai trouvé pour le moment: mater directement le fichier contenant la table, sa date de derniere modification et la comparer avec mon cache. Solution bourrin que j’aimerais éviter.

Quelqu’un a une idée?

[quote name=’[PERE]Cil’ date=’ 20 Jan 2005, 07:02’]La seule solution que j’ai trouvé pour le moment: mater directement le fichier contenant la table, sa date de derniere modification et la comparer avec mon cache. Solution bourrin que j’aimerais éviter.

Quelqu’un a une idée?
[right][post=“324146”]<{POST_SNAPBACK}>[/post][/right][/quote]
Surtout que ca marchera pas, faut pas croire que MySql ecrit sur disque a l’instant ou tu fais une operation (enfin j’espere vraiment pas pour les perfs du truc). Il a aussi son cache et le flush sur disque n’est en theorie qu’une operation asynchrone. En plus a la seconde pres… c’est prendre des gros risques, plusieures centaines d’operations sont possible en une seconde.

Je n’ai jamais mis en place de systeme de cache php, mais voila comment je procederais probablement.

-> Une table “cache” ou chaque ligne correspond a un element en cache. Un element peut etre une page complete, mais cela depend clairement du site que tu developpes. On identifie l’element par un ID unique (md5 de l’url de la page, par exemple).

-> Quand une modification de la page se produit, alors on efface la ligne correspondante dans la table de caches.

-> Quand on accede a une page, alors on regarde si l’element existe en cache. Si oui, on l’utilise (evidemment), sinon, on le cree et on l’enregistre dans le cache.

Apres, faut aussi un systeme qui evalue l’utilite d’un element en cache (pour effacer les elements auquels on accede peu), pour optimiser la taille et l’utilisation du cache.

Petite remarque, mais MD5 sapu a mort pour faire ca. C’est ultra lent. C’est pour faire de la crypto si tu veux un checksum rapide tu peux utiliser CRC c’est bien plus adapté. Et son probleme c’est pas « comment implementer un cache » mais plutot « comment invalider mon cache quand la DB est mise a jour ».

Ce a quoi il faut bien repondre que sans trigger et lancement de code externe, il y a pas de solution simple. Le mieux si il n’y a que ton site qui accede a la DB en question c’est de faire l’invalidation du cote client au moment ou tu lance un update ou un insert, tu invalide toutes les pages qui ont une dependance sur cette table. Comment tu gere la liste des dependances, ca c’est une autre histoire et tu vas devoir maintenir une table de gestion des dependance page/table et chaque page devra se referencer dans cette liste de dependance. Tu es d’ailleurs pas oblige d’en faire un systeme limite aux table MySql ca peut etre base sur un truc bien plus generique qui gere un fichier sur le disque, une table sql, ou autre. Je te conseille de regarder du cote d’asp.net sur la maniere dont ils gerent le caching des pages et la gestions des dependances :stuck_out_tongue: il y a des gens malins qui ont passé un bon moment a essayer de faire un truc generique et modulaire, tu devrais surement y trouver plein de bonnes idees.

Un truc a noter c’est que si la verification de la validite du cache prend aussi lontemps ou trop de temps par rapport a ce qu’il te faut pour redemander les datas, ton cache n’a aucun interet voire, ralenti l’application. Toute requete a la base en particulier est a eviter. A la limite c’est la DB qui dit a l’appli que elle a ete mise a jour, mais si ton cache pour verifier si il est toujours valide ou pas doit acceder a la base, ca n’a quasiement aucun interet a part pour des enormes requetes que tu peux surement optimiser avant de chercher a cacher les resultats…

D’un cote tu touches un peu a THE probleme qui est la zone de recherche numero1 des couches de persistances dans les framework n-tier du web a haut volume. Que ca soit au niveau des pages en sorti (plus facile) ou des objets de persistance (plus compliqué), c’est jamais simple. En parler en PHP c’est a la limite rigolo :stuck_out_tongue: mais je regarderais plutot du coté de Zend et autre plutot que de re-inventer la roue. Parceque toutes ces applis qui sont vendues a la peau des fesses + 1000 sont faites ou defaites principalement par leur strategie de caching et a quel point elles sont faciles a utiliser, optimales, et rapides (enfin la on parle principalement de caching au niveau de la couche buisness logic, pas de caching de page). C’est un peu la que se fait beaucoup de la recherche dans le domaine et un des sujets les plus complexes du developpement multi tier sur le web :P. Cela etant dit, bon courage :stuck_out_tongue:

GloP, je t’aimes. C’était tellement évident. Donc je vais certainement faire comme ca: a ma classe Database (qui dérive de la classe IO et dont ma classe Mysql est issue), je vais lui faire faire des insertions dans une table, et dans une mémoire partagée (si, le php sait faire ca) je stocke pour chaque table la date de derniere mise a jour, et je pourrais invalider ou valider le cache en fonction.

Seul problème: pour un système de forum ca risque d’être le dawa nan? ce système marche bien seulement quand il n’y a pas trop d’insertions dans la table? Un gros forum genre celui ci, le cache doit etre invalidé plusieurs fois par minutes, ce qui me fait poser des questions sur l’efficacité du système (quoique des centaines d’utilisateurs doivent voir les pages entre temps…)

Autre problème: si PHP n’est pas le seul a accéder a la base de donnée, genre une appli en C qui fait des traitements sur les tables a intervalles aléatoires, ca complique encore la chose.

Ps: je fais ca pour ma culture personnelle, pas pour une appli commerciale. Je veux juste savoir comment c’est fait c’est tout.

Naturellement mon système de cache est bien plus rapide que faire les requetes: je cache en fonction du fichier, des paramètres, et du CRC32 du php qui a généré la page (au cas ou s’il y aurait eu une modification du code source). Et je pense qu’avec le coup de la shared memory ca va pas bcp plus la ralentir.

En résumé: insert, update, delete >> hop on met a jour la mémoire partagée. Le cache identifie les tables de la requete de la page, et fait en fonction de l’état des tables stockées dans la mémoire partagée.

Pour ce qui est de l’accès externe, j’réfléchis toujours.