Bagaimana saya bisa tahu kapan tabel MySQL terakhir diperbarui?

176

Di bagian bawah halaman saya, saya ingin menambahkan sesuatu seperti "terakhir diperbarui xx / xx / 200x" dengan tanggal ini menjadi yang terakhir kali tabel mySQL tertentu telah diperbarui.

Apa cara terbaik untuk melakukannya? Apakah ada fungsi untuk mengambil tanggal yang terakhir diperbarui? Haruskah saya mengakses ke database setiap kali saya membutuhkan nilai ini?

Kemarahan
sumber

Jawaban:

276

Di versi MySQL yang lebih baru, Anda dapat menggunakan information_schemadatabase untuk memberi tahu Anda ketika tabel lain diperbarui:

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

Ini tentu saja berarti membuka koneksi ke database.


Opsi alternatif adalah "menyentuh" ​​file tertentu setiap kali tabel MySQL diperbarui:

Tentang pembaruan basis data:

  • Buka file stempel waktu Anda dalam O_RDRWmode
  • close lagi

atau sebagai alternatif

  • gunakan touch(), fungsi yang setara dengan PHP utimes(), untuk mengubah stempel waktu file.

Pada tampilan halaman:

  • gunakan stat()untuk membaca kembali waktu modifikasi file.
Alnitak
sumber
9
Untuk detail termasuk batasan InnoDB lihat dev.mysql.com/doc/refman/5.5/en/show-table-status.html ( show table statusmenggunakan information_schema.tables)
KCD
11
Kedua UPDATE_TIMEmetode dan show table statusmetode di bawah ini hanya tersedia dengan mesin MyISAM, tidak InnoDB. Meskipun ini terdaftar sebagai bug , disebutkan dalam Referensi MySQL 5.5 , yang juga mengatakan bahwa file_per_tablemode adalah indikator waktu modifikasi yang tidak dapat diandalkan.
idoimaging
5
Sekali lagi, tidak bekerja pada InnoDB karena mysql adalah f ** king buggy: bugs.mysql.com/bug.php?id=14374
TMS
7
Untuk MySQL 5.7.2+ ini juga berfungsi untuk InnoDB : "Dimulai dengan MySQL 5.7.2, UPDATE_TIME menampilkan nilai timestamp untuk UPDATE, INSERT, atau DELETE terakhir yang dilakukan pada tabel InnoDB yang tidak dipartisi. Sebelumnya, UPDATE_TIME menampilkan nilai NULL untuk tabel InnoDB. "
Peter V. Mørch
2
Ini sepertinya tidak bertahan saat restart untuk saya (pada versi 5.7.11).
58

Saya tidak memiliki database information_schema, menggunakan mysql versi 4.1.16, jadi dalam hal ini Anda dapat menanyakan ini:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

Ini akan mengembalikan kolom ini:

| Nama | Mesin | Versi | Format Row_ | Baris | Avg_row_length 
| Data_length | Max_data_length | Index_length | Data_free | Auto_increment
| Buat_waktu | Update_time | Check_time | Collation
| Checksum | Buat_pilihan | Komentar |

Seperti yang Anda lihat ada kolom bernama: " Update_time " yang menunjukkan Anda waktu pembaruan terakhir untuk your_table .

Radu Maris
sumber
2
Ini juga berkinerja lebih cepat (4x) kemudian pernyataan SELECT
jmav
1
Bahkan, sebagian besar perintah SHOW seperti ini hanya dipetakan ke query Information_schema secara internal, jadi jawaban ini memberikan data yang persis sama dengan jawaban dari Alnitak di atas. Dan ajacian81 benar - tidak berfungsi untuk mesin penyimpanan default MySQL, InnoDB.
Bill Karwin
55

Saya terkejut tidak ada yang menyarankan pelacakan waktu pembaruan terakhir per baris:

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;

Ini memperbarui cap waktu meskipun kami tidak menyebutkannya di 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 |
+----+------+---------------------+

Sekarang Anda dapat meminta MAX ():

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

Harus diakui, ini membutuhkan lebih banyak penyimpanan (4 byte per baris untuk TIMESTAMP).
Tapi ini bekerja untuk tabel InnoDB sebelum versi 5.7.15 MySQL, yang INFORMATION_SCHEMA.TABLES.UPDATE_TIMEtidak.

Bill Karwin
sumber
10
+1 Sejauh yang saya ketahui, ini adalah satu-satunya jawaban yang tepat untuk pertanyaan ini. Pertanyaannya benar-benar ingin tahu kapan data yang relevan diperbarui, dan bukan kapan tabel (yang tidak relevan bagi pengguna) mungkin atau mungkin tidak diubah karena alasan apa pun.
siride
23
Tetapi jika Anda menghapus catatan dengan waktu pembaruan yang lebih rendah, MAX (updated_at) tidak akan berfungsi.
Ammamon
3
@Ammamon, benar, jika Anda juga perlu memperhitungkan penghapusan, solusi ini tidak mencerminkan hal itu. Pemicu untuk memperbarui tabel ringkasan mungkin merupakan satu-satunya solusi komprehensif, tetapi itu akan membuat kemacetan.
Bill Karwin
2
untuk sebagian besar kasus, mengetahui penghapusan tidak akan relevan, dan banyak aps tingkat lebih tinggi tidak benar-benar menghapus dari banyak tabel tetapi hanya mengeset flag untuk yang setara.
Samuel Fullman
1
@Pavan, tidak ada perbedaan, Anda hanya mengandalkan perilaku default, dan contoh saya menjabarkan opsi secara eksplisit. Tetapi opsinya identik dengan perilaku default.
Bill Karwin
13

Hal paling sederhana adalah memeriksa cap waktu file tabel pada disk. Misalnya, Anda dapat memeriksa di bawah direktori data Anda

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

Ini akan memberi Anda daftar semua tabel dengan tabel saat terakhir kali diubah, yang tertua.

pengguna2654744
sumber
Jawaban yang sangat bagus karena UPDATE_TIME adalah NULL untuk semua tabel dalam case saya (MariaDb)
Alexander Vasiljev
file ibd hanya menyimpan struktur tabel. Secara default, data disimpan dalam ibdata1 sehingga stempel waktu file ibd tidak akan diperbarui ketika data diubah dalam tabel. https://dev.mysql.com/doc/refman/8.0/id/show-table-status.html
Stack Underflow
7

Untuk daftar perubahan tabel terbaru gunakan ini:

SELECT UPDATE_TIME, TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY UPDATE_TIME DESC, TABLE_SCHEMA, TABLE_NAME
Francois Bourgeois
sumber
3
Mengapa semua saya UPDATE_TIMEnol? Ada ide?
Metafaniel
5
UPDATE_TIME Anda nol karena Anda menggunakan InnoDB alih-alih MyISAM. InnoDB umumnya merupakan pilihan yang lebih baik, tetapi tidak mendukung UPDATE_TIME.
Xaraxia
5

Saya akan membuat pemicu yang menangkap semua pembaruan / memasukkan / menghapus dan menulis stempel waktu di tabel kustom, seperti tablename | cap waktu

Hanya karena saya tidak suka ide untuk membaca tabel sistem internal server db secara langsung

Mikhail
sumber
1
Ini sepertinya solusi yang baik untuk MS SQL, karena tidak ada UPDATE_TIMEkolom seperti di MySQL.
Darcy
3

Meskipun ada jawaban yang diterima saya tidak merasa itu adalah jawaban yang tepat. Ini adalah cara paling sederhana untuk mencapai apa yang dibutuhkan, tetapi bahkan jika sudah diaktifkan di InnoDB (sebenarnya dokumen memberi tahu Anda bahwa Anda masih harus mendapatkan NULL ...), jika Anda membaca dokumen MySQL , bahkan dalam versi saat ini (8.0) menggunakan UPDATE_TIME adalah bukan opsi yang tepat, karena:

Stempel waktu tidak bertahan saat server dihidupkan ulang atau saat tabel diusir dari cache kamus data InnoDB.

Jika saya mengerti dengan benar (tidak dapat memverifikasinya di server sekarang), timestamp akan diatur ulang setelah server restart.

Adapun solusi nyata (dan, juga, mahal), Anda memiliki Bill Karwin solusi dengan CURRENT_TIMESTAMP dan saya ingin mengusulkan satu yang berbeda, yang didasarkan pada pemicu (Saya menggunakan yang satu).

Anda mulai dengan membuat tabel terpisah (atau mungkin Anda memiliki beberapa tabel lain yang dapat digunakan untuk tujuan ini) yang akan berfungsi seperti penyimpanan untuk variabel global (di sini cap waktu). Anda perlu menyimpan dua bidang - nama tabel (atau nilai apa pun yang ingin Anda simpan di sini sebagai id tabel) dan cap waktu. Setelah Anda memilikinya, Anda harus menginisialisasi dengan tabel ini id + tanggal mulai (SEKARANG () adalah pilihan yang baik :)).

Sekarang, Anda pindah ke tabel yang ingin Anda amati dan tambahkan pemicu SETELAH INSERT / UPDATE / HAPUS dengan prosedur ini atau yang serupa:

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

Analisis tingkat OS:

Temukan tempat DB disimpan di disk:

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

Periksa modifikasi terbaru

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

Harus bekerja pada semua tipe database.

John McLean
sumber
0

Hanya ambil tanggal file yang diubah dari sistem file. Dalam bahasa saya itu adalah:

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

Keluaran:

1/25/2013 06:04:10 AM
Steve Wood
sumber
6
sepertinya hack yang sangat non portable, cara standar yang akan bekerja di mana saja akan lebih baik
Tejesh Alimilli
0

Jika Anda menjalankan Linux, Anda dapat menggunakan inotify untuk melihat tabel atau direktori database. inotify tersedia dari PHP, node.js, perl dan saya menduga sebagian besar bahasa lain. Tentu saja Anda harus menginstal inotify atau ISP Anda menginstalnya. Banyak ISP tidak mau.

bartonlp
sumber
2
Pemeriksaan sistem file tidak berguna jika database Anda berjalan di server yang terpisah
Sam Dufel
0

Tidak yakin apakah ini menarik. Menggunakan mysqlproxy di antara mysql dan klien, dan memanfaatkan skrip lua untuk memperbarui nilai kunci dalam memcached menurut perubahan tabel yang menarik UPDATE, DELETE, INSERT adalah solusi yang saya lakukan baru-baru ini. Jika bungkus mendukung pengait atau pemicu di php, ini bisa jadi lebih mudah. Tak satu pun dari pembungkus saat ini melakukan ini.

Jiju Thomas Mathew
sumber
0

saya membuat kolom dengan nama: update-at di phpMyAdmin dan mendapatkan waktu saat ini dari metode Date () dalam kode saya (nodejs). dengan setiap perubahan dalam tabel, kolom ini menampung waktu perubahan.

berkata
sumber
1
Selamat datang di StackOverflow! Harap edit jawaban Anda untuk memasukkan beberapa kode yang Anda gunakan, serta penjelasan mengapa Anda memilih untuk melakukannya dengan cara ini. Pertanyaan ini sudah hampir sebelas tahun , dan sudah memiliki jawaban yang diterima dan dijabarkan dengan baik. Jawaban Anda, tanpa kode atau penjelasan, kemungkinan akan diturunkan atau dihapus. Mengeditnya untuk memasukkan hal-hal itu akan membantu membenarkan tempatnya pada pos ini.
Das_Geek
0

a) Ini akan menampilkan semua tabel dan ada tanggal pembaruan terakhir

SHOW TABLE STATUS FROM db_name;

kemudian, Anda selanjutnya dapat meminta tabel spesifik:

SHOW TABLE STATUS FROM db_name like 'table_name';

b) Seperti dalam contoh di atas Anda tidak dapat menggunakan pengurutan pada 'Update_time' tetapi menggunakan SELECT Anda dapat:

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

untuk bertanya lebih lanjut tentang tabel tertentu:

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

Inilah yang saya lakukan, saya harap ini membantu.

<?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'];
    }
?>
Andrés Chandía
sumber
2
Mengapa Anda menggunakan seperti di sini?
Kyle Buser
3
@WesleyMurch: tag <i> sudah usang.
siride
-9

Tembolok kueri dalam variabel global saat itu tidak tersedia.

Buat halaman web untuk memaksa cache dimuat ulang saat Anda memperbaruinya.

Tambahkan panggilan ke halaman reload ke skrip penerapan Anda.

Kieveli
sumber
2
Anda tidak dapat "cache" variabel antara pemanggilan independen halaman PHP tanpa bantuan dari luar.
Alnitak