MySQLテーブルが最後に更新された時期を知るにはどうすればよいですか?


176

ページのフッターに、「最後に更新されたxx / xx / 200x」のようなものを追加します。この日付は、特定のmySQLテーブルが最後に更新された日付です。

それを行う最良の方法は何ですか?最終更新日を取得する機能はありますか?この値が必要になるたびにデータベースにアクセスする必要がありますか?


回答:


276

MySQLの以降のバージョンでは、information_schemaデータベースを使用して、別のテーブルが更新された時期を通知できます。

SELECT UPDATE_TIME
FROM   information_schema.tables
WHERE  TABLE_SCHEMA = 'dbname'
   AND TABLE_NAME = 'tabname'

もちろん、これはデータベースへの接続を開くことを意味します。


別のオプションは、MySQLテーブルが更新されるたびに特定のファイルを「タッチ」することです。

データベースの更新時:

  • O_RDRWモードでタイムスタンプファイルを開く
  • close もう一度

または代わりに

  • touch()PHPのutimes()関数に相当するを使用して、ファイルのタイムスタンプを変更します。

ページ表示:

  • stat()ファイル変更時刻を読み戻すために使用します。

9
InnoDBの制限を含む詳細については、dev.mysql.com / doc / refman / 5.5 / en / showshow table statusinformation_schema.tables
KCD

11
UPDATE_TIMEメソッドとshow table status以下のメソッドはどちらもMyISAMエンジンでのみ使用でき、InnoDBでは使用できません。これはバグとしてリストされていますが、MySQL 5.5リファレンスで言及されています。これは、file_per_tableモードが変更時間の信頼できないインジケータであることも示しています。
idoimaging 2012

5
繰り返しますが、mysqlはバグが多いので、InnoDBでは機能しません:bugs.mysql.com/bug.php?id
TMS

7
MySQL 5.7.2以降では、InnoDBでも機能します。「MySQL 5.7.2以降、UPDATE_TIMEは、パーティション化されていないInnoDBテーブルで実行された最後のUPDATE、INSERT、またはDELETEのタイムスタンプ値を表示します。以前は、UPDATE_TIMEはNULL値を表示していました。 InnoDBテーブル用。」
PeterV.Mørch、2015

2
これは、再起動時に持続しないようです(バージョン5.7.11)。

58

mysqlバージョン4.1.16を使用しているinformation_schemaデータベースがないので、この場合はこれをクエリできます。

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

次の列を返します。

| 名前| エンジン| バージョン| Row_format | 行| Avg_row_length 
| データ長| Max_data_length | Index_length | Data_free | Auto_increment
| Create_time | Update_time | Check_time | 照合
| チェックサム| Create_options | コメント|

「:あなたが見ることができるようにという列がありUPDATE_TIME」ことを示してあなたのための最終更新時間your_tableが


2
また、より高速(4x)でSELECTステートメントを実行します
jmav

1
実際、このようなほとんどのSHOWコマンドは、Information_schemaクエリに内部的にマッピングされるだけなので、この回答は、上記のAlnitakからの回答とまったく同じデータを提供します。そしてajacian81は正解です。MySQLのデフォルトストレージエンジンであるInnoDBでは機能しません。
ビルカーウィン2014

55

行ごとに最終更新時間を追跡することを提案した人がいないことに驚いています。

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;

これは、UPDATEでタイムスタンプに言及していなくても、タイムスタンプを更新します。

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 |
+----+------+---------------------+

これで、MAX()を照会できます。

mysql> SELECT MAX(updated_at) FROM foo;
+---------------------+
| MAX(updated_at)     |
+---------------------+
| 2013-08-21 03:30:20 |
+---------------------+

確かに、これにはより多くのストレージが必要です(TIMESTAMPの行ごとに4バイト)。
しかし、これはMySQLのバージョン5.7.15より前のInnoDBテーブルINFORMATION_SCHEMA.TABLES.UPDATE_TIMEは機能しますが、機能しません。


10
+1私に関する限り、これがこの質問に対する唯一の正しい答えです。質問は、関連するデータがいつ更新されたかを知りたいのであり、(ユーザーに関係のない)テーブルが何らかの理由で変更されたかどうかはわかりません。
siride 2013

23
ただし、更新時間が短いレコードを削除すると、MAX(updated_at)は機能しません。
Ammamon 2014年

3
@Ammamon、真、削除も考慮する必要がある場合、このソリューションはそれを反映していません。要約テーブルを更新するトリガーが唯一の包括的なソリューションである可能性がありますが、それはボトルネックを作成します。
ビルカーウィン2014年

2
ほとんどの場合、削除を知ることはそれほど重要ではなく、多くの高レベルのAPは多くのテーブルから本当に削除するのではなく、単に同等のフラグの設定を解除します。
サミュエルフルマン2014

1
@Pavan、違いはありません。デフォルトの動作に依存しているだけで、私の例ではオプションを明示的に説明しています。ただし、オプションはデフォルトの動作と同じです。
ビルカーウィン、

13

最も簡単なのは、ディスク上のテーブルファイルのタイムスタンプを確認することです。たとえば、データディレクトリの下で確認できます

cd /var/lib/mysql/<mydatabase>
ls -lhtr *.ibd

これにより、最後に最後に変更されたときのテーブルを含むすべてのテーブルのリストが最初に表示されます。


私の(MariaDb)ケースのすべてのテーブルでUPDATE_TIMEがNULLであるため、本当に素晴らしい答え
Alexander Vasiljev

ibdファイルはテーブル構造のみを保存します。デフォルトでは、データはibdata1に格納されるため、テーブルでデータが変更されてもibdファイルのタイムスタンプは更新されません。https://dev.mysql.com/doc/refman/8.0/en/show-table-status.html
Stack Underflow

7

最近のテーブル変更のリストについては、これを使用してください:

SELECT UPDATE_TIME, TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY UPDATE_TIME DESC, TABLE_SCHEMA, TABLE_NAME

3
なぜすべてUPDATE_TIMEがnullなのですか?何か案が?
メタファニエル2017

5
MyISAMの代わりにInnoDBを使用しているため、UPDATE_TIMEはnullです。通常、InnoDBの方が適していますが、UPDATE_TIMEはサポートされていません。
Xaraxia 2017年

5

私はすべての更新/挿入/削除をキャッチし、カスタムテーブルにタイムスタンプを書き込むトリガーを作成します。タイムスタンプ

DBサーバーの内部システムテーブルを直接読み取るのが嫌いだから


1
UPDATE_TIMEMySQLのような列がないため、これはMS SQLの良いソリューションのようです。
ダーシー2013

3

受け入れられた答えはありますが、私はそれが正しいものだとは思いません。これは必要なものを達成する最も簡単な方法ですが、InnoDBですでに有効になっている場合でも(実際にはドキュメントでNULLを取得する必要があることがわかります...)、現在のバージョン(8.0)でも、MySQL ドキュメントを読んだ場合、UPDATE_TIMEを使用すると次の理由により、適切なオプションではありません。

サーバーが再起動されたとき、またはテーブルがInnoDBデータディクショナリキャッシュから削除されたとき、タイムスタンプは保持されません。

私が正しく理解している場合(現在サーバーで確認できない場合)、サーバーの再起動後にタイムスタンプがリセットされます。

実際の(そしてまあ、コストのかかる)ソリューションについては、CURRENT_TIMESTAMPを使用したBill Karwinのソリューションがあり、トリガーに基づいた別のソリューションを提案したいと思います(私はそのソリューションを使用しています)。

まず、グローバル変数(ここではタイムスタンプ)のストレージのように機能する別のテーブル(または、この目的で使用できる他のテーブルがある)を作成します。2つのフィールドを保存する必要があります-テーブル名(または、ここにテーブルIDとして保持したい任意の値)とタイムスタンプ。取得したら、このテーブルID +開始日で初期化する必要があります(NOW()が適切な選択です:))。

次に、監視するテーブルに移動し、次の手順または同様の手順でINSERT / UPDATE / DELETEの後にトリガーを追加します。

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

OSレベルの分析:

DBがディスクに保存されている場所を見つけます。

grep datadir /etc/my.cnf
datadir=/var/lib/mysql

最新の変更を確認する

cd /var/lib/mysql/{db_name}
ls -lrt

すべてのデータベースタイプで機能するはずです。


0

ファイルシステムから変更されたファイルの日付を取得するだけです。私の言語では:

 tbl_updated = file.update_time(
        "C:\ProgramData\MySQL\MySQL Server 5.5\data\mydb\person.frm")

出力:

1/25/2013 06:04:10 AM

6
非常に移植性のないハックのように見え、どこでも機能する標準的な方法の方が良いでしょう
Tejesh Alimilli

0

Linuxを実行している場合は、inotifyを使用してテーブルまたはデータベースディレクトリを確認できます。inotifyはPHP、node.js、perlから入手でき、他のほとんどの言語が疑われます。もちろん、inotifyをインストールしたか、ISPにインストールしてもらう必要があります。多くのISPはそうしません。


2
データベースが別のサーバーで実行されている場合、ファイルシステムのチェックは役に立ちません
Sam Dufel

0

これがどんな興味を引くかはわかりません。mysqlとクライアント間でmysqlproxyを使用し、luaスクリプトを使用して、興味深いテーブル変更UPDATE、DELETE、INSERTに従ってmemcachedのキー値を更新することは、私が最近行った解決策でした。ラッパーがphpでフックまたはトリガーをサポートしている場合、これはもっと簡単かもしれません。現在のところ、これを行うラッパーはありません。


0

名前で列を作成しました:phpMyAdminのupdate-atで、コード(nodejs)のDate()メソッドから現在の時刻を取得しました。テーブルのすべての変更で、この列は変更の時間を保持します。


1
StackOverflowへようこそ!回答編集して、使用したコードの一部と、この方法を選択した理由の説明を含めてください。この質問はほぼ11年前のものであり、すでに認められ、よく賛成されている答えがあります。コードや説明がなければ、回答は反対投票または削除される可能性があります。それらを含めるように編集すると、この投稿での位置付けを正当化するのに役立ちます。
Das_Geek

0

a)すべてのテーブルと最終更新日が表示されます

SHOW TABLE STATUS FROM db_name;

次に、さらに特定のテーブルを要求できます。

SHOW TABLE STATUS FROM db_name like 'table_name';

b)上記の例のように、 'Update_time'でソートを使用することはできませんが、SELECTを使用すると次のことができます。

SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' ORDER BY UPDATE_TIME DESC;

特定のテーブルについてさらに質問するには:

SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' AND table_name='table_name' ORDER BY UPDATE_TIME DESC';

-1

これは私がやったことです、それが役に立てば幸いです。

<?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'];
    }
?>

2
なぜここのように使うのですか?
Kyle Buser 2013年

3
@WesleyMurch:<font>タグは非推奨になりました。
siride 2013

-9

使用できない場合は、クエリをグローバル変数にキャッシュします。

更新時にキャッシュを強制的に再読み込みするWebページを作成します。

リロードページへの呼び出しをデプロイメントスクリプトに追加します。


2
外部の支援なしでは、PHPページの独立した呼び出し間で変数を「キャッシュ」することはできません。
アルニタク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.