जब एक 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/show-table-status.html ( show table statusउपयोग information_schema.tables)
KCD

11
दोनों UPDATE_TIMEविधि और show table statusनीचे की विधि केवल MyISAM इंजन के साथ उपलब्ध है, न कि InnoDB। यद्यपि यह एक बग के रूप में सूचीबद्ध है , यह MySQL 5.5 संदर्भ में उल्लिखित है , जो यह भी कहता है कि file_per_tableमोड संशोधन समय का एक अविश्वसनीय संकेतक है।
निष्क्रिय करना

5
फिर से, InnoDB पर काम नहीं करता क्योंकि mysql f ** king छोटी गाड़ी है: 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 तालिकाओं के लिए। "
पीटर वी। मॉर्क

2
यह मेरे लिए पुनः आरंभ (संस्करण 5.7.11 पर) पर कायम नहीं लगता है।

58

मेरे पास mysql संस्करण 4.1.16 का उपयोग करते हुए info_schema डेटाबेस नहीं है, इसलिए इस मामले में आप इसे क्वेरी कर सकते हैं:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

यह इन कॉलमों को लौटाएगा:

| नाम | इंजन | संस्करण | रोवफॉर्म | पंक्तियाँ | औसत_रो_लिफ्ट 
| Data_length | Max_data_length | Index_length | Data_free | Auto_increment
| क्रिएट_टाइम | अपडेट_टाइम | चेक_टाइम | कोलाज
| चेकसम | Create_options | टिप्पणी |

जैसा कि आप देख सकते हैं कि एक कॉलम है: " Update_time " जो आपको आपके_समय के लिए अंतिम अपडेट समय दिखाता है


2
यह तेजी से (4x) प्रदर्शन भी करता है, फिर कथन
jmav

1
वास्तव में, इस तरह के ज्यादातर SHOW कमांड केवल आंतरिक रूप से Information_schema प्रश्नों के लिए मैप किए जाते हैं, इसलिए यह उत्तर बिल्कुल वैसा ही डेटा देता है जैसा कि Alnitak के उत्तर से दिया गया है। और ajacian81 सही है - यह MySQL के डिफ़ॉल्ट भंडारण इंजन, InnoDB के लिए काम नहीं करता है।
बिल करविन

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

बेशक, इसके लिए अधिक संग्रहण की आवश्यकता है (TIMESTAMP के लिए प्रति पंक्ति 4 बाइट्स)।
लेकिन यह MySQL के 5.7.15 संस्करण से पहले InnoDB तालिकाओं के लिए काम करता है , जो INFORMATION_SCHEMA.TABLES.UPDATE_TIMEनहीं करता है।


10
+1 जहाँ तक मेरा सवाल है, यह इस सवाल का एकमात्र सही उत्तर है। यह प्रश्न वास्तव में जानना चाहता है कि प्रासंगिक डेटा कब अपडेट किया गया है, और तब नहीं जब कोई तालिका (जो उपयोगकर्ता के लिए अप्रासंगिक है) जो भी कारण से बदल दी गई हो या नहीं।
सिराइड

23
लेकिन अगर आप कम अपडेट समय के साथ रिकॉर्ड हटाते हैं, तो MAX (अपडेट_ट) काम नहीं करेगा।
अम्माँ

3
@Ammamon, सच है, अगर आपको भी विलोपन के लिए खाते की आवश्यकता है, तो यह समाधान प्रतिबिंबित नहीं करता है। सारांश तालिका को अद्यतन करने के लिए एक ट्रिगर केवल व्यापक समाधान हो सकता है, लेकिन यह एक अड़चन पैदा करेगा।
बिल करविन

2
विलोपन जानने वाले अधिकांश उदाहरणों के लिए प्रासंगिक नहीं होगा, और कई उच्च स्तरीय एप्स वास्तव में कई तालिकाओं से नहीं हटते हैं, लेकिन बस समकक्ष के लिए एक ध्वज को अनसेट करते हैं।
शमूएल फुलमैन

1
@Pavan, कोई अंतर नहीं है, आप बस डिफ़ॉल्ट व्यवहार पर भरोसा कर रहे हैं, और मेरा उदाहरण स्पष्ट रूप से विकल्प को मंत्र देता है। लेकिन विकल्प डिफ़ॉल्ट व्यवहार के समान है।
बिल कार्विन

13

सबसे सरल बात यह होगी कि डिस्क पर टेबल फ़ाइलों के टाइमस्टैम्प की जांच करें। उदाहरण के लिए, आप अपने डेटा निर्देशिका के तहत जाँच कर सकते हैं

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

यह आपको तालिका के साथ सभी तालिकाओं की सूची देनी चाहिए जब इसे अंतिम बार सबसे पुराना समय संशोधित किया गया था, पहले।


UPDATE_TIME के ​​बाद से वास्तव में बहुत अच्छा जवाब मेरे (मारियाडब) मामले में सभी तालिकाओं के लिए NULL है
अलेक्जेंडर

आईबीडी फाइलें केवल टेबल संरचना को संग्रहीत करती हैं। डिफ़ॉल्ट रूप से, डेटा को ibdata1 में संग्रहीत किया जाता है ताकि ibd फ़ाइल टाइमस्टैम्प तालिका में डेटा परिवर्तित होने पर अपडेट न हो। https://dev.mysql.com/doc/refman/8.0/en/show-table-status.html
स्टैक अंडरफ्लो

7

हाल की तालिका परिवर्तनों की सूची के लिए इसका उपयोग करें:

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

3
मेरे सभी UPDATE_TIMEअशक्त क्यों हैं? कोई उपाय?
मेटाफैनियल

5
आपका UPDATE_TIME शून्य है क्योंकि आप MyISAM के बजाय InnoDB का उपयोग कर रहे हैं। InnoDB आम तौर पर बेहतर विकल्प है, लेकिन यह UPDATE_TIME का समर्थन नहीं करता है।
1

5

मैं एक ट्रिगर बनाऊंगा जो सभी अपडेट्स / इंसर्ट / डिलीट को पकड़ता है और कस्टम टेबल में टाइमस्टैम्प लिखता है, कुछ ऐसा है जैसे टैब्लेन | टाइमस्टैम्प

सिर्फ इसलिए कि मुझे db सर्वर की आंतरिक प्रणाली तालिकाओं को सीधे पढ़ने का विचार पसंद नहीं है


1
यह MS SQL के लिए एक अच्छा समाधान की तरह लगता है, क्योंकि UPDATE_TIMEMySQL में कोई कॉलम नहीं है ।
डार्सी

3

यद्यपि एक स्वीकृत उत्तर है, मुझे नहीं लगता कि यह सही है। यह सबसे आसान तरीका है जिसे हासिल करने की आवश्यकता है, लेकिन यहां तक ​​कि अगर पहले से ही InnoDB में सक्षम है (वास्तव में डॉक्स आपको बताते हैं कि आपको अभी भी NULL मिलना चाहिए ...), यदि आप MySQL डॉक्स पढ़ते हैं, तो भी वर्तमान संस्करण (8.0) में UPD_TIME का उपयोग किया जा रहा है सही विकल्प नहीं, क्योंकि:

सर्वर रिस्टार्ट होने पर या जब InnoDB डेटा डिक्शनरी कैश से टेबल को निकाला जाता है तो टाइमस्टैम्प्स कायम नहीं रहते हैं।

अगर मैं सही तरीके से समझता हूं (इसे अभी सर्वर पर सत्यापित नहीं किया जा सकता है), सर्वर रिस्टार्ट होने के बाद टाइमस्टैम्प रीसेट हो जाता है।

वास्तविक (और, अच्छी तरह से, महंगा) समाधानों के लिए, आपके पास CURRENT_TIMESTAMP के साथ बिल कारविन का समाधान है और मैं एक अलग प्रस्ताव देना चाहूंगा, जो ट्रिगर्स पर आधारित है (मैं उस एक का उपयोग कर रहा हूं)।

आप एक अलग तालिका बनाकर शुरू करते हैं (या हो सकता है कि आपके पास कुछ अन्य तालिका हो जो इस उद्देश्य के लिए उपयोग की जा सकती हैं) जो वैश्विक चर (यहां टाइमस्टैम्प) के लिए भंडारण की तरह काम करेंगी। आपको दो फ़ील्ड्स संग्रहीत करने की आवश्यकता है - टेबल का नाम (या टेबल आईडी के रूप में आप यहां जो भी मूल्य रखना चाहते हैं) और टाइमस्टैम्प। आपके पास यह होने के बाद, आपको इसे इस तालिका आईडी + प्रारंभिक तिथि (अब () एक अच्छा विकल्प है :)) के साथ प्रारंभ करना चाहिए।

अब, आप उन तालिकाओं पर जाते हैं जिन्हें आप निरीक्षण करना चाहते हैं और इस तरह की प्रक्रिया के साथ 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
बेहद गैर पोर्टेबल हैक की तरह लग रहा है, एक मानक तरीका है कि हर जगह काम करेगा बेहतर होगा
तेजेश अलिमिल्ली

0

यदि आप लिनक्स चला रहे हैं, तो आप तालिका या डेटाबेस निर्देशिका को देखने के लिए inotify का उपयोग कर सकते हैं। inotify PHP, node.js, perl से उपलब्ध है और मुझे अधिकांश अन्य भाषाओं पर संदेह है। निश्चित रूप से आपने अपने ISP को इनस्टॉल करना या स्थापित किया होगा। बहुत आईएसपी नहीं होगा।


2
यदि आपका डेटाबेस एक अलग सर्वर पर चल रहा है तो फाइलसिस्टम जांच उपयोगी नहीं है
सैम ड्यूफेल

0

यकीन नहीं होता कि यह किसी हित का होगा। Mysqlproxy का उपयोग mysql और क्लाइंट के बीच में करना, और दिलचस्प तालिका परिवर्तन UPDATE, DELETE, INSERT के अनुसार एक महत्वपूर्ण मान को अपडेट करने के लिए एक लुआ स्क्रिप्ट का उपयोग करना। INSERT वह समाधान था जो मैंने हाल ही में किया था। यदि रैपर php में हुक या ट्रिगर्स का समर्थन करता है, तो यह ईजीज़र हो सकता है। अब तक कोई भी रैपर ऐसा नहीं करता है।


0

मैंने नाम से एक कॉलम बनाया: phpMyAdmin में अपडेट-ऑन और मेरे कोड (नोडज) में दिनांक () विधि से वर्तमान समय मिला। तालिका में हर परिवर्तन के साथ यह कॉलम परिवर्तनों का समय रखता है।


1
StackOverflow में आपका स्वागत है! कृपया आपके द्वारा उपयोग किए गए कुछ कोड को शामिल करने के लिए अपने उत्तर को संपादित करें , साथ ही इस बात का स्पष्टीकरण भी दिया कि आपने इसे इस तरह क्यों चुना। यह सवाल लगभग ग्यारह साल पुराना है , और पहले से ही एक स्वीकृत, अच्छी तरह से उत्कीर्ण जवाब है। आपका जवाब, कुछ कोड या स्पष्टीकरण के बिना, संभावना कम या हटा दिया जाएगा। उन चीजों को शामिल करने के लिए इसे संपादित करने से इस पोस्ट पर अपनी जगह को सही ठहराने में मदद मिलेगी।
दास_गीक

0

a) यह आपको सभी टेबल दिखाएगा और अंतिम अपडेट की तारीखें हैं

SHOW TABLE STATUS FROM db_name;

फिर, आप विशिष्ट तालिका के लिए आगे पूछ सकते हैं:

SHOW TABLE STATUS FROM db_name like 'table_name';

बी) ऊपर दिए गए उदाहरणों के अनुसार आप 'Update_time' पर छँटाई का उपयोग नहीं कर सकते हैं, लेकिन आप का चयन कर सकते हैं:

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
आप यहाँ की तरह क्यों इस्तेमाल करेंगे?
काइल बसर

3
@WesleyMurch: <font> टैग रास्ता-रहित है।
2:22 बजे

-9

जब यह उपलब्ध नहीं हो तो वैश्विक चर में क्वेरी को कैश करें।

जब आप इसे अपडेट करते हैं तो कैश को फिर से लोड करने के लिए मजबूर करने के लिए एक वेबपेज बनाएं।

अपनी परिनियोजन स्क्रिप्ट में पुनः लोड करने वाले पृष्ठ पर कॉल जोड़ें।


2
आप बाहरी सहायता के बिना PHP पृष्ठ के स्वतंत्र चालान के बीच "कैश" चर नहीं कर सकते।
अलनीतक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.