Dans le pied de page, j'aimerais ajouter quelque chose comme "dernière mise à jour le xx/xx/200x", cette date étant la dernière mise à jour d'une certaine table mySQL.
Quelle est la meilleure façon de le faire? Existe-t-il une fonction permettant de récupérer la dernière date de mise à jour? Devrais-je accéder à la base de données chaque fois que j'ai besoin de cette valeur?
Dans les versions ultérieures de MySQL, vous pouvez utiliser la base de données information_schema
pour indiquer quand une autre table a été mise à jour:
SELECT UPDATE_TIME
FROM information_schema.tables
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'tabname'
Cela signifie bien entendu ouvrir une connexion à la base de données.
Une autre option serait de "toucher" un fichier particulier chaque fois que la table MySQL est mise à jour:
Sur les mises à jour de la base de données:
O_RDRW
close
encoreou bien
touch()
, l'équivalent PHP de la fonction utimes()
, pour modifier l'horodatage du fichier.Sur l'affichage de la page:
stat()
pour relire l'heure de modification du fichier.Je n'ai pas de base de données information_schema, j'utilise mysql version 4.1.16, donc dans ce cas, vous pouvez interroger ceci:
SHOW TABLE STATUS FROM your_database LIKE 'your_table';
Il retournera ces colonnes:
Nom | Moteur | Version | Row_format | Rangées | Avg_row_length
| Longueur_données | Max_data_length | Longueur_index | Data_free | Incrémentation automatique
| Create_time | Temps de mise à jour | Check_time | Collation
| Somme de contrôle | Create_options | Commentaire |
Comme vous pouvez le constater, la colonne " Update_time " indique la dernière heure de mise à jour de your_table .
Je suis surpris que personne n'ait suggéré de suivre la dernière mise à jour par ligne:
mysql> CREATE TABLE foo (
id INT PRIMARY KEY
x INT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
KEY (updated_at)
);
mysql> INSERT INTO foo VALUES (1, NOW() - INTERVAL 3 DAY), (2, NOW());
mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x | updated_at |
+----+------+---------------------+
| 1 | NULL | 2013-08-18 03:26:28 |
| 2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+
mysql> UPDATE foo SET x = 1234 WHERE id = 1;
Ceci met à jour l'horodatage même si nous ne l'avons pas mentionné dans la mise à jour.
mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x | updated_at |
+----+------+---------------------+
| 1 | 1235 | 2013-08-21 03:30:20 | <-- this row has been updated
| 2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+
Maintenant, vous pouvez interroger MAX ():
mysql> SELECT MAX(updated_at) FROM foo;
+---------------------+
| MAX(updated_at) |
+---------------------+
| 2013-08-21 03:30:20 |
+---------------------+
Certes, cela nécessite plus de stockage (4 octets par ligne pour TIMESTAMP).
Mais cela fonctionne pour les tables InnoDB avant la version 5.7.15 de MySQL, ce que INFORMATION_SCHEMA.TABLES.UPDATE_TIME
ne fait pas.
Pour une liste des modifications récentes de la table, utilisez ceci:
SELECT UPDATE_TIME, TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY UPDATE_TIME DESC, TABLE_SCHEMA, TABLE_NAME
Le plus simple serait de vérifier l'horodatage des fichiers de table sur le disque. Par exemple, vous pouvez vérifier sous votre répertoire de données
cd /var/lib/mysql/<mydatabase>
ls -lhtr *.ibd
Cela devrait vous donner la liste de toutes les tables avec la dernière date de modification, la plus ancienne en premier.
Je créerais un déclencheur qui intercepte toutes les mises à jour/insertions/suppressions et écrit l'horodatage dans une table personnalisée, quelque chose comme Tablename | horodatage
Juste parce que je n'aime pas l'idée de lire directement les tables système internes du serveur de base de données
Bien qu'il y ait une réponse acceptée, je ne pense pas que ce soit la bonne. C’est le moyen le plus simple de réaliser ce qui est nécessaire, mais même si déjà activé dans InnoDB (docs vous dit que vous devez toujours obtenir NULL ...), si vous lisez MySQL -docs , même dans la version actuelle ) utiliser UPDATE_TIME n’est pas la bonne option, car:
Les horodatages ne sont pas conservés lorsque le serveur est redémarré ou lorsque le fichier table est expulsée du cache du dictionnaire de données InnoDB.
Si je comprends bien (je ne peux pas le vérifier sur un serveur pour le moment), l'horodatage est réinitialisé après le redémarrage du serveur.
En ce qui concerne les solutions réelles (et coûteuses), vous avez la solution/ de Bill Karwin avec CURRENT_TIMESTAMP et j'aimerais proposer une solution différente, basée sur des déclencheurs (je l’utilise également).
Vous commencez par créer une table séparée (ou peut-être une autre table pouvant être utilisée à cette fin) qui fonctionnera comme un stockage pour les variables globales (ici les horodatages). Vous devez stocker deux champs - nom de la table (ou la valeur que vous souhaitez conserver ici comme identifiant de table) et horodatage. Une fois que vous l'avez, vous devez l'initialiser avec cet identifiant de table + date de début (NOW () est un bon choix :)).
Maintenant, déplacez-vous vers les tables que vous souhaitez observer et ajoutez des déclencheurs APRES INSERTION/MISE A JOUR/SUPPRIMER avec cette procédure ou une procédure similaire:
CREATE PROCEDURE `timestamp_update` ()
BEGIN
UPDATE `SCHEMA_NAME`.`TIMESTAMPS_TABLE_NAME`
SET `timestamp_column`=DATE_FORMAT(NOW(), '%Y-%m-%d %T')
WHERE `table_name_column`='TABLE_NAME';
END
Si vous utilisez Linux, vous pouvez utiliser inotify pour consulter la table ou le répertoire de la base de données. inotify est disponible à partir de PHP, node.js, Perl et je soupçonne la plupart des autres langues. Bien sûr, vous devez avoir installé inotify ou le faire installer par votre FAI. Beaucoup de FAI ne le feront pas.
Il suffit de saisir la date du fichier modifié à partir du système de fichiers. Dans ma langue c'est:
tbl_updated = file.update_time(
"C:\ProgramData\MySQL\MySQL Server 5.5\data\mydb\person.frm")
Sortie:
1/25/2013 06:04:10 AM
Analyse au niveau du système d'exploitation:
Recherchez l'emplacement de la base de données sur le disque:
grep datadir /etc/my.cnf
datadir=/var/lib/mysql
Vérifier les dernières modifications
cd /var/lib/mysql/{db_name}
ls -lrt
Devrait fonctionner sur tous les types de bases de données.
Je ne sais pas si cela pourrait vous intéresser. Utiliser mysqlproxy entre mysql et les clients, et utiliser un script lua pour mettre à jour une valeur de clé dans memcached en fonction de changements de tables intéressants. Si l'encapsuleur prenait en charge les crochets ou les déclencheurs dans php, cela aurait pu être plus simple. Aucun des emballages à l'heure actuelle ne le fait.