Comment puis-je savoir quand une table MySQL a été mise à jour pour la dernière fois?
Dans le pied de page de ma page, je voudrais ajouter quelque chose comme "dernière mise à jour du xx/xx/200x" avec cette date étant la dernière fois qu'une certaine table mySQL a été mise à jour.
Quelle est la meilleure façon de le faire? Est-il une fonction pour récupérer la dernière date de mise à jour? Dois-je accéder à la base de données chaque fois que j'ai besoin de cette valeur?
13 réponses
Dans les versions ultérieures de MySQL, vous pouvez utiliser la base de données information_schema
pour vous 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 sûr 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:
- ouvrez votre fichier d'horodatage en mode
O_RDRW
-
close
encore
Ou alternativement
- utilisation
touch()
, l'équivalent PHP de la fonctionutimes()
, pour changer l'horodatage du fichier.
Sur l'affichage de la page:
- utilisez
stat()
pour relire l'Heure de modification du fichier.
Je n'ai pas de base de données information_schema, en utilisant mysql version 4.1.16, donc dans ce cas, vous pouvez interroger ceci:
SHOW TABLE STATUS FROM your_database LIKE 'your_table';
Il renverra ces colonnes:
| Name | Engine | Version | Row_format | Rows | Avg_row_length
| Data_length | Max_data_length | Index_length | Data_free | Auto_increment
| Create_time | Update_time | Check_time | Collation
| Checksum | Create_options | Comment |
Comme vous pouvez le voir, il y a une colonne appelée: " Update_time " qui vous montre la dernière heure de mise à jour pour your_table.
Je suis surpris que personne n'ait suggéré de suivre l'Heure de 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;
Cela 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 le 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 L'horodatage).
Mais cela fonctionne pour les tables InnoDB avant la version 5.7.15 de MySQL, ce qui n'est pas le cas de INFORMATION_SCHEMA.TABLES.UPDATE_TIME
.
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
Je créerais un déclencheur qui attrape toutes les mises à jour / insertions / suppressions et écrirais 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 db
La chose la plus simple serait de vérifier l'horodatage des fichiers de table sur le disque. Par exemple, Vous pouvez vérifier dans 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 table quand elle a été modifiée la dernière fois, en premier.
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
Si vous utilisez Linux, vous pouvez utiliser inotify pour regarder 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 votre FAI l'a installé. Beaucoup de FAI ne sera pas.
Je ne sais pas si cela serait d'un intérêt. L'utilisation de mysqlproxy entre mysql et les clients, et l'utilisation d'un script lua pour mettre à jour une valeur clé dans memcached en fonction des changements de table intéressants UPDATE,DELETE,INSERT était la solution que j'ai fait tout récemment. Si le wrapper supportait des hooks ou des triggers en php, cela aurait pu être eaiser. Aucun des emballages ne le fait maintenant.
Analyse du niveau du système D'exploitation:
Trouvez où la base de données est stockée sur le disque:
grep datadir /etc/my.cnf
datadir=/var/lib/mysql
Vérifiez les modifications les plus récentes
cd /var/lib/mysql/{db_name}
ls -lrt
Devrait fonctionner sur tous les types 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 s'il est déjà activé dans InnoDB (en fait, les documents vous disent que vous devriez toujours obtenir NULL ...), si vous lisez MySQL docs , même dans la version actuelle (8.0), l'utilisation de UPDATE_TIME n'est pas la bonne option, car:
Les horodatages ne sont pas persistants lorsque le serveur est redémarré ou lorsque la table est expulsée du dictionnaire de données InnoDB cache.
Si je comprends bien (je ne peux pas le vérifier sur un serveur en ce moment), l'horodatage est réinitialisé après le redémarrage du serveur.
En ce qui concerne les solutions réelles (et, bien, coûteuses), vous avez la solution de Bill Karwin avec CURRENT_TIMESTAMP et j'aimerais en proposer une autre, basée sur des déclencheurs (j'utilise celle-ci).
Vous commencez par créer une table séparée (ou peut-être avez-vous une autre table qui peut être utilisée à cette fin) qui fonctionnera comme un stockage pour variables globales (ici horodatages). Vous devez stocker deux champs - Nom de la table (ou quelle que soit la valeur que vous souhaitez conserver ici comme ID de table) et horodatage. Après l'avoir, vous devriez l'initialiser avec cet ID de table + date de début (NOW() est un bon choix:)).
Maintenant, vous passez aux tables que vous souhaitez observer et ajoutez des déclencheurs après INSERT / UPDATE / DELETE 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
C'est ce que j'ai fait, j'espère que ça aide.
<?php
mysql_connect("localhost", "USER", "PASSWORD") or die(mysql_error());
mysql_select_db("information_schema") or die(mysql_error());
$query1 = "SELECT `UPDATE_TIME` FROM `TABLES` WHERE
`TABLE_SCHEMA` LIKE 'DataBaseName' AND `TABLE_NAME` LIKE 'TableName'";
$result1 = mysql_query($query1) or die(mysql_error());
while($row = mysql_fetch_array($result1)) {
echo "<strong>1r tr.: </strong>".$row['UPDATE_TIME'];
}
?>
Met en Cache la requête dans une variable globale lorsqu'elle n'est pas disponible.
Créez une page Web pour forcer le rechargement du cache lorsque vous le mettez à jour.
Ajoutez un appel à la page de rechargement dans vos scripts de déploiement.