Bir MySQL tablosunun en son ne zaman güncellendiğini nasıl anlayabilirim?


176

Sayfamın altbilgisinde, "son güncelleme xx / xx / 200x" gibi bir şey eklemek istiyorum, bu tarih belirli bir mySQL tablosunun son güncellenme tarihi.

Bunu yapmanın en iyi yolu nedir? Son güncellenme tarihini almak için bir işlev var mı? Bu değere her ihtiyaç duyduğumda veritabanına erişmeli miyim?


Yanıtlar:


276

MySQL'in sonraki sürümlerinde, information_schemabaşka bir tablonun ne zaman güncellendiğini söylemek için veritabanını kullanabilirsiniz :

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

Bu elbette veritabanına bir bağlantı açmak anlamına gelir.


Alternatif bir seçenek, MySQL tablosu her güncellendiğinde belirli bir dosyaya "dokunmak" olacaktır:

Veritabanı güncellemelerinde:

  • Zaman damgası dosyanızı O_RDRWmodunda açın
  • close tekrar dene

Veya alternatif olarak

  • Dosya zaman damgasını değiştirmek için işlevin touch()PHP eşdeğerini kullanın utimes().

Sayfa ekranında:

  • stat()dosya değiştirme zamanını okumak için kullanın .

9
InnoDB sınırlamaları dahil ayrıntılar için bkz. Dev.mysql.com/doc/refman/5.5/en/show-table-status.html ( show table statuskullanım alanları information_schema.tables)
KCD

11
Hem UPDATE_TIMEyöntem hem de show table statusaşağıdaki yöntem InnoDB ile değil, yalnızca MyISAM motoruyla kullanılabilir. Bu bir hata olarak listelenmesine rağmen , modun modifikasyon süresinin güvenilir olmayan bir göstergesi olduğunu söyleyen MySQL 5.5 Referansında belirtilmiştir file_per_table.
idoimaging

5
Yine, InnoDB üzerinde çalışmıyor çünkü mysql f ** king buggy: bugs.mysql.com/bug.php?id=14374
TMS

7
MySQL 5.7.2+ için de çalışır InnoDB : "MySQL 5.7.2 ile başlayarak, UPDATE_TIME, bölümlenmemiş InnoDB tablolarında gerçekleştirilen son UPDATE, INSERT veya DELETE için bir zaman damgası değeri görüntüler. InnoDB tabloları için. "
Peter V.Mørch

2
Bu benim için yeniden başlatma devam gibi görünmüyor (sürüm 5.7.11).

58

Ben mysql sürüm 4.1.16 kullanarak information_schema veritabanı yok, bu durumda bu sorgulayabilirsiniz:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

Şu sütunları döndürür:

| İsim | Motor | Versiyon | Row_format | Satırlar | Ort. Satır_uzunluğu 
| Veri_uzunluğu | Maks_veri_uzunluğu | Dizin_uzunluğu | Veri_ücretsiz | Otomatik_yükleme
| Oluşturma zamanı | Güncelleme_zamanı | Kontrol_zamanı | Harmanlama
| Sağlama Toplamı | Seçenekler_ | Yorum |

": Eğer adında bir sütun vardır görebileceğiniz gibi UPDATE_TIME " için son güncelleme zamanı olduğunu gösterir size your_table .


2
Ayrıca daha hızlı (4x) sonra SELECT deyimi
jmav

1
Aslında, bunun gibi çoğu SHOW komutu dahili olarak Information_schema sorgularıyla eşleştirilir, bu nedenle bu cevap yukarıdaki Alnitak'ın cevabı ile tamamen aynı verileri verir. Ve ajacian81 doğrudur - MySQL'in varsayılan depolama motoru InnoDB için çalışmaz.
Bill Karwin

56

Kimsenin satır başına son güncelleme zamanını takip etmesini önermediğine şaşırdım:

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;

Bu, UPDATE'te bahsetmemiş olsak da zaman damgasını günceller.

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

Şimdi MAX () için sorgu yapabilirsiniz:

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

Kuşkusuz, bu daha fazla depolama alanı gerektirir (TIMESTAMP için satır başına 4 bayt).
Ama bu InnoDB tabloları için çalışır MySQL 5.7.15 sürümü, daha önce INFORMATION_SCHEMA.TABLES.UPDATE_TIMEdeğil.


10
+1 Bence bu soruya verilen tek doğru cevap bu. Soru gerçekten ilgili verilerin ne zaman güncellendiğini bilmek istemektedir (bir tablo (kullanıcıyla ilgisiz)) herhangi bir nedenle değiştirilip değiştirilemeyeceğini bilmek istemez.
siride

23
Ancak daha düşük güncelleme süresine sahip bir kaydı silerseniz MAX (updated_at) çalışmaz.
Ammamon

3
@Ammamon, doğru, silme işlemlerini de hesaba katmanız gerekirse, bu çözüm bunu yansıtmaz. Özet tablosunu güncellemek için tetikleyici tek kapsamlı çözüm olabilir, ancak bu bir darboğaz yaratacaktır.
Bill Karwin

2
silme işlemini bilen çoğu örnek o kadar alakalı olmaz ve birçok üst düzey aps birçok tablodan gerçekten silmez, ancak eşdeğer bir bayrağın işaretini kaldırır.
Samuel Fullman

1
@Pavan, fark yok, sadece varsayılan davranışa güveniyorsunuz ve örneğim seçeneği açıkça belirtiyor. Ancak seçenek, varsayılan davranışla aynıdır.
Bill Karwin

13

En basit şey, diskteki tablo dosyalarının zaman damgasını kontrol etmek olacaktır. Örneğin, veri dizininizi kontrol edebilirsiniz

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

Bu, ilk olarak en son değiştirildiği zaman tabloya sahip tüm tabloların listesini vermelidir.


UPDATE_TIME (MariaDb) davamdaki tüm tablolar için NULL olduğu için gerçekten harika bir cevap
Alexander Vasiljev

ibd dosyaları yalnızca tablo yapısını saklar. Varsayılan olarak, veriler ibdata1 içinde saklanır, böylece tablodaki veriler değiştirildiğinde ibd dosyası zaman damgası güncellenmez. https://dev.mysql.com/doc/refman/8.0/en/show-table-status.html
Yığın Altını

@StackUnderflow, Söyledikleriniz doğru değil. İbd dosyaları, bir veya daha fazla tablo içeren bir tablo alanının verilerini ve dizinlerini depolar. Veriler ibdata1 içinde depolanırsa ibd dosyası olmayacaktır. 2013 yılında MySQL 5.6'dan bu yana tablo başına bir dosyada veri depolamak varsayılan
değerdir

7

Son tablo değişikliklerinin listesi için şunu kullanın:

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

3
Neden hepsi UPDATE_TIMEnull? Herhangi bir fikir?
Metafaniel

5
MyISAM yerine InnoDB kullandığınız için UPDATE_TIME değeriniz boş. InnoDB genellikle daha iyi bir seçimdir, ancak UPDATE_TIME'ı desteklemez.
Xaraxia

5

Tüm güncelleştirmeleri / ekler / siler ve özel tablo, zaman çizelgesi yazma tablename gibi bir şey yakalar bir tetikleyici oluşturmak istiyorum | Zaman damgası

Sadece doğrudan db sunucusunun iç sistem tablolarını okuma fikrini sevmiyorum çünkü


1
Bu MS SQL için iyi bir çözüm gibi görünüyor, çünkü MySQL'de olduğu UPDATE_TIMEgibi bir sütun yok .
Darcy

3

Kabul edilmiş bir cevap olmasına rağmen doğru cevap olduğunu düşünmüyorum. Gerekli olanı elde etmenin en basit yoludur, ancak InnoDB'de zaten etkin olsa bile (aslında dokümanlar size hala NULL almanız gerektiğini söyler ...), MySQL belgelerini okursanız , UPDATE_TIME kullanarak bile doğru seçenek değil, çünkü:

Sunucu yeniden başlatıldığında veya tablo InnoDB veri sözlüğü önbelleğinden çıkarıldığında zaman damgaları kalıcı olmaz.

Doğru anlıyorsam (şu anda sunucuda doğrulayamıyorum), sunucu yeniden başlatıldıktan sonra zaman damgası sıfırlanır.

Gerçek (ve, iyi, maliyetli) çözümlere gelince, Bill Karwin'in CURRENT_TIMESTAMP ile çözümüne sahipsiniz ve tetikleyicilere dayanan farklı bir tane önermek istiyorum (bunu kullanıyorum).

Genel değişkenler (burada zaman damgaları) için bir depolama alanı gibi çalışacak ayrı bir tablo oluşturarak (veya belki de bu amaçla kullanılabilecek başka bir tablonuz var) başlarsınız. İki alan - tablo adı (veya burada tablo kimliği olarak tutmak istediğiniz herhangi bir değer) ve zaman damgası depolamanız gerekir. Elinize geçtikten sonra, bu tablo kimliği + başlangıç ​​tarihi ile başlatmalısınız (ŞİMDİ () iyi bir seçimdir :)).

Şimdi, gözlemlemek istediğiniz tablolara geçersiniz ve bu veya benzer prosedürle INSERT / UPDATE / DELETE SONRASI tetikleyiciler eklersiniz:

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

İşletim sistemi seviyesi analizi:

DB'nin diskte nerede depolandığını bulun:

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

En son değişiklikleri kontrol edin

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

Tüm veritabanı türlerinde çalışmalıdır.


0

Sadece dosya sisteminden değiştirilen dosya tarihini alın. Kendi dilimde:

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

Çıktı:

1/25/2013 06:04:10 AM

6
son derece taşınabilir olmayan bir kesmek gibi görünüyor, her yerde çalışmak için standart bir yol daha iyi olurdu
Tejesh Alimilli

0

Linux çalıştırıyorsanız, tabloya veya veritabanı dizinine bakmak için inotify kullanabilirsiniz. inotify PHP, node.js, perl adresinden edinilebilir ve diğer birçok dilden şüpheleniyorum. Tabii ki inotify kurmuş veya ISS'nizi kurmuş olmalısınız. Bir çok ISS yapmayacak.


2
Veritabanınız ayrı bir sunucuda çalışıyorsa dosya sistemi kontrolleri işe
yaramaz

0

Bunun herhangi bir ilgisinin olup olmayacağından emin değilim. Mysql ve istemciler arasında mysqlproxy kullanma ve ilginç tablo değişikliklere göre memcached bir anahtar değerini güncellemek için bir lua komut dosyası kullanarak UPDATE, DELETE, INSERT oldukça son zamanlarda yaptığım çözüm oldu. Sarıcı destek kanca veya php tetikler, bu hevesli olabilirdi. Şimdilik hiçbir paketleyici bunu yapmıyor.


0

i adıyla bir sütun yaptı: phpMyAdmin güncelleme-at ve benim kod (nodejs) Date () yönteminden şimdiki zaman var. tablodaki her değişiklikle birlikte bu sütun değişikliklerin zamanını tutar.


1
StackOverflow'a hoş geldiniz! Lütfen yanıtınızı , kullandığınız kodun bazılarını içerecek şekilde ve bunun neden bu şekilde yapmayı seçtiğinize ilişkin bir açıklama içerecek şekilde düzenleyin . Bu soru neredeyse on bir yaşında ve zaten kabul edilmiş, iyi bir cevabı var. Herhangi bir kod veya açıklama olmadan cevabınız büyük olasılıkla reddedilecek veya silinecektir. Bunları içerecek şekilde düzenlemek, bu yayındaki yerini haklı çıkarmaya yardımcı olacaktır.
Das_Geek

0

a) Size tüm tabloları ve son güncelleme tarihlerini gösterecektir

SHOW TABLE STATUS FROM db_name;

daha sonra, belirli bir tablo isteyebilirsiniz:

SHOW TABLE STATUS FROM db_name like 'table_name';

b) Yukarıdaki örneklerde olduğu gibi 'Güncelleme_zamanı' üzerinde sıralamayı kullanamazsınız, ancak SELECT kullanarak şunları yapabilirsiniz:

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

belirli bir tablo hakkında daha fazla soru sormak için:

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

-1

Ben de öyle yaptım, umarım yardımcı olur.

<?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
Neden burada gibi kullanasýn ki?
Kyle Buser

3
@WesleyMurch: <font> etiketi kullanımdan kaldırıldı.
siride

-9

Kullanılabilir olmadığında sorguyu genel bir değişkende önbelleğe alın.

Güncelleştirdiğinizde önbelleği yeniden yüklenmeye zorlamak için bir web sayfası oluşturun.

Yeniden yükleme sayfasına dağıtım komut dosyalarınıza bir çağrı ekleyin.


2
dışarıdan yardım almadan bir PHP sayfasının bağımsız çağrıları arasında değişkenleri "önbelleğe alamaz".
Alnitak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.