web-dev-qa-db-fra.com

Comment savoir quand une table MySQL a été mise à jour pour la dernière fois?

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?

153
RaGE

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:

  • Ouvrez votre fichier d'horodatage en mode O_RDRW
  • close encore

ou bien

  • utilisez touch() , l'équivalent PHP de la fonction utimes(), pour modifier l'horodatage du fichier.

Sur l'affichage de la page:

  • utilisez stat() pour relire l'heure de modification du fichier.
243
Alnitak

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 .

53
Radu Maris

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.

46
Bill Karwin

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
6
Francois Bourgeois

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.

5
user2654744

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

5
Mikhail

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
1
Soul Reaver

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.

0
bartonlp

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
0
Steve Wood

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.

0
John McLean

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. 

0
Jiju Thomas Mathew