ฉันจะบอกได้อย่างไรเมื่อตาราง MySQL ได้รับการปรับปรุงล่าสุด


176

ในส่วนท้ายของหน้าของฉันฉันต้องการเพิ่มบางอย่างเช่น "ปรับปรุงครั้งล่าสุด xx / xx / 200x" ด้วยวันที่นี้เป็นครั้งสุดท้ายที่ตาราง mySQL บางตัวได้รับการปรับปรุง

วิธีที่ดีที่สุดในการทำเช่นนั้นคืออะไร? มีฟังก์ชั่นในการดึงข้อมูลวันที่อัพเดทล่าสุดหรือไม่? ฉันควรเข้าถึงฐานข้อมูลทุกครั้งที่ต้องการค่านี้หรือไม่?


ที่เกี่ยวข้อง: stackoverflow.com/questions/12563706/…
Pekka

คำตอบ:


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/show-table-status.html (การshow table statusใช้งานinformation_schema.tables)
KCD

11
ทั้งUPDATE_TIMEวิธีการและshow table statusวิธีการด้านล่างมีให้เฉพาะกับเครื่องมือ MyISAM ไม่ใช่ InnoDB แม้ว่าสิ่งนี้จะถูกระบุว่าเป็นบั๊กแต่ก็มีการกล่าวถึงในMySQL 5.5 Referenceซึ่งยังกล่าวว่าfile_per_tableโหมดนี้เป็นตัวบ่งชี้ที่ไม่น่าเชื่อถือของเวลาในการแก้ไข
idoimaging

5
อีกครั้งไม่ทำงานบน InnoDB เนื่องจาก mysql เป็น f ** king buggy: bugs.mysql.com/bug.php?id=14374
TMS

7
สำหรับ MySQL 5.7.2+ มันยังสามารถใช้งานกับ InnoDB ได้ด้วย : "เริ่มต้นด้วย MySQL 5.7.2, UPDATE_TIME แสดงค่าการประทับเวลาสำหรับ UPDATE, INSERT หรือ DELETE ล่าสุดที่ดำเนินการบนตาราง InnoDB ที่ไม่ได้แบ่งพาร์ติชันก่อนหน้านี้ UPDATE_TIME แสดงค่า NULL สำหรับตาราง InnoDB "
Peter V. Mørch

2
ดูเหมือนว่าจะยังคงมีอยู่เมื่อรีสตาร์ทสำหรับฉัน (ในรุ่น 5.7.11)

58

ฉันไม่มีฐานข้อมูล information_schema โดยใช้ mysql เวอร์ชัน 4.1.16 ดังนั้นในกรณีนี้คุณสามารถสืบค้นสิ่งนี้:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

มันจะกลับคอลัมน์เหล่านี้:

| ชื่อ | เครื่องยนต์ | รุ่น | Row_format | แถว | Avg_row_length 
| Data_length | Max_data_length | ดัชนี _length | Data_free | Auto_increment
| Create_time | Update_time | Check_time | Collation
| เช็คซัม Create_options | ความคิดเห็น |

ที่คุณสามารถดูมีคอลัมน์ที่เรียกว่า " UPDATE_TIME " ที่แสดงให้เห็นว่าคุณเป็นครั้งสุดท้ายสำหรับการปรับปรุงyour_table


2
นอกจากนี้ยังทำงานได้เร็วขึ้น (4x) แล้วเลือกคำสั่ง
jmav

1
ในความเป็นจริงคำสั่ง SHOW ส่วนใหญ่เช่นนี้จะถูกแมปกับเคียวรี Information_schema เป็นการภายในดังนั้นคำตอบนี้ให้ข้อมูลเหมือนกับคำตอบจาก Alnitak ด้านบนทั้งหมด และ ajacian81 นั้นถูกต้อง - มันไม่ทำงานสำหรับเอ็นจิ้นเก็บข้อมูลเริ่มต้นของ MySQL InnoDB
Bill Karwin

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;

สิ่งนี้อัปเดตการประทับเวลาแม้ว่าเราจะไม่ได้กล่าวถึงในการอัปเดต

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

เป็นที่ยอมรับว่าต้องใช้พื้นที่เก็บข้อมูลเพิ่มเติม (4 ไบต์ต่อแถวสำหรับ TIMESTAMP)
แต่วิธีนี้ใช้ได้กับตาราง InnoDBก่อน MySQL เวอร์ชัน 5.7.15 ซึ่งINFORMATION_SCHEMA.TABLES.UPDATE_TIMEไม่ได้


10
+1 เท่าที่ฉันกังวลนี่เป็นคำตอบที่ถูกต้องสำหรับคำถามนี้ คำถามอยากรู้ว่าข้อมูลที่เกี่ยวข้องนั้นมีการอัพเดทจริงหรือไม่และเมื่อใดที่ตาราง (ซึ่งไม่เกี่ยวข้องกับผู้ใช้) อาจเปลี่ยนแปลงหรือไม่ได้รับการเปลี่ยนแปลงด้วยเหตุผลใด ๆ ก็ตาม
siride

23
แต่ถ้าคุณลบระเบียนด้วยเวลาอัปเดตที่ต่ำกว่า MAX (updated_at) จะไม่ทำงาน
Ammamon

3
@Ammamon จริงถ้าคุณจำเป็นต้องคำนึงถึงการลบด้วยวิธีนี้ไม่ได้สะท้อนถึงสิ่งนั้น ทริกเกอร์เพื่ออัปเดตตารางสรุปอาจเป็นโซลูชันเดียวที่ครอบคลุม แต่จะสร้างคอขวด
Bill Karwin

2
สำหรับอินสแตนซ์ส่วนใหญ่ที่ทราบว่าการลบจะไม่เกี่ยวข้องและ aps ระดับสูงกว่านั้นไม่ได้ลบจากหลาย ๆ ตาราง แต่เพียงยกเลิกการตั้งค่าสถานะสำหรับเทียบเท่า
ซามูเอลฟูลแมน

1
@Pavan ไม่มีความแตกต่างคุณพึ่งพึ่งพฤติกรรมเริ่มต้นและตัวอย่างของฉันสะกดตัวเลือกออกมาอย่างชัดเจน แต่ตัวเลือกจะเหมือนกับพฤติกรรมเริ่มต้น
Bill Karwin

13

สิ่งที่ง่ายที่สุดคือการตรวจสอบการประทับเวลาของไฟล์ตารางบนดิสก์ ตัวอย่างเช่นคุณสามารถตรวจสอบภายใต้ไดเรกทอรีข้อมูลของคุณ

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

สิ่งนี้จะให้รายการของตารางทั้งหมดที่มีตารางเมื่อมีการปรับเปลี่ยนครั้งล่าสุดเป็นเวลาที่เก่าที่สุดก่อน


จริงๆคำตอบที่ดีตั้งแต่ UPDATE_TIME เป็นโมฆะสำหรับตารางทั้งหมดใน (MariaDB) กรณีของฉัน
อเล็กซานเด 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เป็นโมฆะ? ความคิดใด ๆ
Metafaniel

5
UPDATE_TIME ของคุณไม่มีค่าเนื่องจากคุณใช้ InnoDB แทน MyISAM โดยทั่วไปแล้ว InnoDB เป็นตัวเลือกที่ดีกว่า แต่ไม่รองรับ UPDATE_TIME
Xaraxia

5

ฉันจะสร้างทริกเกอร์ที่จับการปรับปรุง / แทรก / ลบและเขียนการประทับเวลาทั้งหมดในตารางที่กำหนดเองบางอย่างเช่น tablename | การประทับเวลา

เพียงเพราะฉันไม่ชอบความคิดในการอ่านตารางระบบภายในของเซิร์ฟเวอร์ db โดยตรง


1
ดูเหมือนว่าจะเป็นทางออกที่ดีสำหรับ MS SQL เพราะไม่มีUPDATE_TIMEคอลัมน์เหมือนใน MySQL
Darcy

3

แม้ว่าจะมีคำตอบที่ยอมรับ แต่ฉันก็ไม่รู้สึกว่ามันเป็นคำตอบที่ถูกต้อง มันเป็นวิธีที่ง่ายที่สุดในการบรรลุสิ่งที่ต้องการ แต่แม้ว่าจะเปิดใช้งานแล้วใน InnoDB (เอกสารจริงบอกคุณว่าคุณยังควรได้รับ NULL ... ) ถ้าคุณอ่าน MySQL docsแม้ในเวอร์ชันปัจจุบัน (8.0) โดยใช้ UPDATE_TIME คือ ไม่ใช่ตัวเลือกที่ถูกต้องเพราะ:

การประทับเวลาจะไม่คงอยู่เมื่อเซิร์ฟเวอร์เริ่มต้นใหม่หรือเมื่อตารางถูกขับออกจากแคชพจนานุกรมข้อมูล InnoDB

หากฉันเข้าใจถูกต้อง (ไม่สามารถตรวจสอบได้บนเซิร์ฟเวอร์ตอนนี้) เวลาประทับจะถูกรีเซ็ตหลังจากเซิร์ฟเวอร์รีสตาร์ท

สำหรับโซลูชันจริง (และดีราคาแพง) คุณมีโซลูชันของ Bill Karwin ที่มี CURRENT_TIMESTAMP และฉันต้องการเสนออีกวิธีหนึ่งซึ่งอิงกับทริกเกอร์ (ฉันใช้อันนั้น)

คุณเริ่มต้นด้วยการสร้างตารางแยกต่างหาก (หรือบางทีคุณอาจมีตารางอื่น ๆ ที่สามารถใช้สำหรับวัตถุประสงค์นี้) ซึ่งจะทำงานเหมือนที่เก็บข้อมูลสำหรับตัวแปรทั่วโลก (ที่นี่การประทับเวลา) คุณต้องจัดเก็บสองฟิลด์ - ชื่อตาราง (หรือค่าใด ๆ ที่คุณต้องการเก็บไว้ที่นี่เป็นรหัสตาราง) และการประทับเวลา หลังจากที่คุณมีคุณควรเริ่มต้นด้วย id ตารางนี้ + วันที่เริ่มต้น (ตอนนี้ () เป็นตัวเลือกที่ดี :))

ตอนนี้คุณย้ายไปยังตารางที่คุณต้องการสังเกตและเพิ่มทริกเกอร์หลังจากแทรก / ปรับปรุง / ลบด้วยขั้นตอนนี้หรือขั้นตอนที่คล้ายกัน:

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:

ค้นหาตำแหน่งที่เก็บฐานข้อมูลบนดิสก์:

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

ไม่แน่ใจว่าสิ่งนี้จะเป็นประโยชน์หรือไม่ การใช้ mysqlproxy ระหว่าง mysql และไคลเอนต์และใช้ประโยชน์จากสคริปต์ lua เพื่ออัปเดตค่าคีย์ใน memcached ตามการเปลี่ยนแปลงตารางที่น่าสนใจ UPDATE, DELETE, INSERT เป็นวิธีแก้ปัญหาที่ฉันทำเมื่อไม่นานมานี้ หาก wrapper รองรับ hooks หรือ trigger ใน php สิ่งนี้อาจเป็น eaiser ไม่มีสิ่งที่ห่อหุ้มในขณะนี้ทำเช่นนี้


0

ฉันสร้างคอลัมน์ตามชื่อ: update-at ใน phpMyAdmin และรับเวลาปัจจุบันจากวิธี Date () ในรหัสของฉัน (nodejs) ในทุกการเปลี่ยนแปลงในตารางคอลัมน์นี้จะถือเวลาของการเปลี่ยนแปลง


1
ยินดีต้อนรับสู่ StackOverflow! โปรดแก้ไขคำตอบของคุณเพื่อรวมรหัสบางส่วนที่คุณใช้รวมถึงคำอธิบายว่าทำไมคุณถึงเลือกใช้วิธีนี้ คำถามนี้อายุเกือบสิบเอ็ดปีแล้วและมีคำตอบที่ยอมรับแล้ว คำตอบของคุณหากไม่มีรหัสหรือคำอธิบายอาจจะถูกลดระดับลงหรือถูกลบ การแก้ไขเพื่อรวมสิ่งเหล่านั้นจะช่วยแสดงให้เห็นถึงตำแหน่งในโพสต์นี้
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

3
@WesleyMurch: แท็ก <font> เป็นวิธีที่เลิกใช้
siride

-9

แคชแบบสอบถามในตัวแปรส่วนกลางเมื่อไม่พร้อมใช้งาน

สร้างเว็บเพจเพื่อบังคับให้โหลดแคชซ้ำเมื่อคุณอัปเดต

เพิ่มการเรียกไปยังหน้าการโหลดซ้ำลงในสคริปต์การปรับใช้ของคุณ


2
คุณไม่สามารถตัวแปร "แคช" ระหว่างการเรียกใช้อิสระของหน้า PHP โดยปราศจากความช่วยเหลือจากภายนอก
Alnitak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.