Как узнать, когда в последний раз обновлялась таблица MySQL?

В нижнем колонтитуле моей страницы я хотел бы добавить что-то вроде «последнее обновление xx / xx / 200x» с этой датой, когда в последний раз обновлялась определенная таблица mySQL.

Как лучше всего это сделать? Есть ли функция для получения даты последнего обновления? Должен ли я обращаться к базе данных каждый раз, когда мне нужно это значение?

Связанный: stackoverflow.com/questions/12563706/…

Pekka 01.06.2015 08:19
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
186
1
306 140
16
Перейти к ответу Данный вопрос помечен как решенный

Ответы 16

Кэшируйте запрос в глобальной переменной, если она недоступна.

Создайте веб-страницу, чтобы принудительно перезагружать кеш при его обновлении.

Добавьте вызов на страницу перезагрузки в свои сценарии развертывания.

вы не можете «кэшировать» переменные между независимыми вызовами страницы PHP без посторонней помощи.

Alnitak 21.11.2008 04:20
Ответ принят как подходящий

В более поздних версиях 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() для считывания времени модификации файла.

я могу манипулировать этим. означает, что если я хочу изменить значение, которое MySQL дает мне, когда я запускаю этот запрос

user605334 12.04.2011 06:50

Для получения дополнительной информации, включая ограничения InnoDB, см. dev.mysql.com/doc/refman/5.5/en/show-table-status.html (show table status использует information_schema.tables)

KCD 10.05.2012 01:12

Связан ли здесь UPDATE_TIME со временем изменений в информационной схеме, например. только структурные изменения ?? Разве при этом не учитываются изменения, если новые строки вставляются / обновляются / удаляются ??

Aamir Adnan 10.05.2012 16:40

Оба метода UPDATE_TIME и show table status ниже доступны только с движком MyISAM, но не InnoDB. Хотя он указан как ошибка, он упоминается в Справочник по MySQL 5.5, где также говорится, что режим file_per_table является ненадежным индикатором времени модификации.

idoimaging 26.09.2012 01:49

Опять же, не работает на InnoDB, потому что mysql чертовски глючит: bugs.mysql.com/bug.php?id=14374

Innate Imunity is The Way 10.09.2014 11:44

Для MySQL 5.7.2+ это также работает для InnoDB: «Начиная с MySQL 5.7.2, UPDATE_TIME отображает значение отметки времени для последнего UPDATE, INSERT или DELETE, выполненного для таблиц InnoDB, которые не секционированы. Ранее UPDATE_TIME отображал значение NULL для InnoDB столы ".

Peter V. Mørch 26.08.2015 02:23

Кажется, это не сохраняется при перезапуске для меня (в версии 5.7.11).

user977221 29.06.2016 23:40

Пока что у меня все работает нормально. Моя единственная проблема в том, что время обновления сбрасывается на ноль каждый день. Есть идеи?

Alator 01.02.2018 14:00

Есть ли способ получить информацию для таблиц InnoDB в 2018 году?

rain_ 03.05.2018 14:22

@rain_ InnoDB исправляет столбец update_time в MySQL 5.7.2, но не сохраняется при перезапусках сервера (см. bugs.mysql.com/bug.php?id=14374)

Bill Karwin 29.01.2019 20:07

Есть ли способ узнать время последнего обновления определенного поля в таблице?

m-2127 18.07.2019 14:53

У меня нет базы данных information_schema, использующей mysql версии 4.1.16, поэтому в этом случае вы можете запросить это:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

Он вернет эти столбцы:

| Name      | Engine | Version | Row_format | Rows | Avg_row_length 
| Data_length | Max_data_length | Index_length | Data_free | Auto_increment
| Create_time | Update_time | Check_time | Collation
| Checksum | Create_options | Comment |

Как видите, есть столбец под названием «Время обновления», который показывает время последнего обновления для your_table.

Он также работает быстрее (в 4 раза), чем оператор SELECT

jmav 24.01.2013 01:16

Фактически, большинство таких команд SHOW просто внутренне сопоставляются с запросами Information_schema, поэтому этот ответ дает точно такие же данные, что и ответ от Alnitak выше. И ajacian81 верен - он не работает для механизма хранения по умолчанию MySQL, InnoDB.

Bill Karwin 17.02.2014 17:02

Я так и сделал, надеюсь, это поможет.

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

Зачем вам использовать подобное здесь?

Kyle Buser 15.03.2013 01:48

@WesleyMurch: тег <font> устарел.

siride 22.08.2013 06:48

Я бы создал триггер, который улавливает все обновления / вставки / удаления и записывает временную метку в настраиваемую таблицу, что-то вроде tablename | отметка времени

Просто потому, что мне не нравится идея читать внутренние системные таблицы сервера db напрямую

Это кажется хорошим решением для MS SQL, потому что здесь нет столбца UPDATE_TIME, как в MySQL.

Darcy 26.07.2013 23:52

Для списка последних изменений таблицы используйте это:

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

Почему все мои UPDATE_TIME нулевые? Любая идея?

Metafaniel 25.04.2017 19:07

Ваш UPDATE_TIME равен нулю, потому что вы используете InnoDB вместо MyISAM. InnoDB, как правило, лучший выбор, но он не поддерживает UPDATE_TIME.

Xaraxia 03.10.2017 04:55

Просто возьмите дату изменения файла из файловой системы. На моем языке это:

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

Выход:

1/25/2013 06:04:10 AM

выглядит очень непереносимым хаком, стандартный способ, который работал бы везде, был бы лучше

Tejesh Alimilli 20.03.2013 19:51

Если вы используете Linux, вы можете использовать inotify для просмотра таблицы или каталога базы данных. inotify доступен на PHP, node.js, perl и, как я подозреваю, на большинстве других языков. Конечно, у вас должен быть установлен inotify или ваш интернет-провайдер установил его. Много ISP не будет.

Проверки файловой системы бесполезны, если ваша база данных работает на отдельном сервере.

Sam Dufel 18.07.2014 21:00

Я удивлен, что никто не предложил отслеживать время последнего обновления для каждой строки:

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

По общему признанию, для этого требуется больше памяти (4 байта на строку для TIMESTAMP) .
Но это работает для таблиц InnoDB до версии MySQL 5.7.15, чего нет у INFORMATION_SCHEMA.TABLES.UPDATE_TIME.

+1 Насколько я понимаю, это единственно правильный ответ на этот вопрос. Вопрос действительно хочет знать, когда обновляются соответствующие данные, а не когда таблица (которая не имеет отношения к пользователю) может или не могла быть изменена по какой-либо причине.

siride 22.08.2013 06:49

Но если вы удалите запись с меньшим временем обновления, MAX (updated_at) работать не будет.

Ammamon 31.03.2014 12:46

@Ammamon, правда, если вам также нужно учитывать удаления, это решение не отражает этого. Триггер для обновления сводной таблицы может быть единственным комплексным решением, но это создаст узкое место.

Bill Karwin 31.03.2014 22:00

да. Я думаю, что мы также можем обновить постоянную глобальную переменную состояния с помощью new DateTime () всякий раз, когда наша таблица вставляется, обновляется или удаляется. Отображая эту глобальную переменную состояния внизу страницы, вы можете избежать повторных проверок таблицы.

Ammamon 02.04.2014 10:13

Я упоминаю об отображении нижнего колонтитула, потому что это то, что нужно спрашивающему.

Ammamon 02.04.2014 10:27

для большинства случаев, когда известно, что удаление не будет иметь такого значения, и многие приложения более высокого уровня не удаляют на самом деле из многих таблиц, а просто снимают флаг для эквивалента.

Samuel Fullman 24.04.2014 03:21

Для удобства вот заявление об обновлении ALTER TABLE 'foo' ADD 'updated_at' TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; ALTER TABLE 'foo' ADD INDEX ('updated_at');

Joshua 19.08.2014 08:42

Привет, @BillKarwin В чем разница между вашим оператором обновления и этим оператором обновления: ALTER TABLE my_table ADD ModifiedTime TIMESTAMP;, взятый из этой статьи: marcus-povey.co.uk/2013/03/11/…

Pavan 14.05.2015 15:59

@Pavan, «По умолчанию в столбце первый TIMESTAMP есть как DEFAULT CURRENT_TIMESTAMP, так и ON UPDATE CURRENT_TIMESTAMP, если ни один из них не указан явно». dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.htm‌ l

Bill Karwin 14.05.2015 23:50

@BillKarwin не понимает разницы? Мой кажется проще реализовать, и он все равно будет обновлять метку времени при обновлении

Pavan 15.05.2015 05:54

@Pavan, нет никакой разницы, вы просто полагаетесь на поведение по умолчанию, и в моем примере опция явно прописана. Но этот параметр идентичен поведению по умолчанию.

Bill Karwin 15.05.2015 07:43

@BillKarwin после MySQL версии 5.7.15, innoDB теперь работает с полем UPDATE_TIME в таблице information_schema.tables.

Meloman 13.10.2017 14:32

@Meloman, спасибо за подсказку, я это пропустил. Я нашел примечания к выпуску, на самом деле это было в 5.7.2. См. dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-2.html и bugs.mysql.com/bug.php?id=14374.

Bill Karwin 13.10.2017 17:59

SELECT MAX ... может работать медленно с большими таблицами. Таблице с 2,8 миллионами требуется 2,5 секунды для определения MAX (...).

Peter 06.12.2017 20:07

@Peter, Нет, InnoDB прочитает индекс на updated_at, чтобы получить максимальное значение. Не нужно вообще читать таблицу, и не имеет значения, насколько велика таблица. Попробуйте EXPLAIN SELECT MAX(updated_at) ..., и вы увидите «Выберите оптимизированные таблицы». Об этой оптимизации читайте здесь: dev.mysql.com/doc/refman/5.7/en/explain-output.html

Bill Karwin 06.12.2017 20:30

@BillKarwin: Не знаю, что вы имеете в виду под EXPLAIN ... |||| Но я согласен, добавление индекса делает SELECT MAX очень быстрым. Но влияет ли созданный индекс на производительность при вставке, например Вставить сразу 2,8 миллиона строк?

Peter 06.12.2017 22:51

@Peter, да, конечно, у индексов есть накладные расходы. Вы должны решить, хотите ли вы оптимизировать для INSERT или оптимизировать для запросов, использующих индекс. Обычно создание индексов - хороший компромисс. Но мы не должны поддерживать индексы, которые не используются ни в одном из наших запросов.

Bill Karwin 06.12.2017 23:35

@BillKarwin для удаленных записей. Я просто использую COUNT, чтобы вернуть количество строк, а также проверить это. Если запись удалена и никаких обновлений не производилось, то количество строк будет другим, а затем, если новая строка будет вставлена ​​и соответствует предыдущему количеству после удаления строки, мы получим последнюю временную метку для нового строка создана. Мой запрос - SELECT COUNT(*) AS total_rows, UNIX_TIMESTAMP(MAX('updated_at')) AS updated FROM 'table', и затем я проверяю оба, чтобы установить флаг isDirty.

Christos Lytras 31.05.2019 01:39

Тот же ответ здесь, с подсказками по производительности: stackoverflow.com/a/35362997/411189

isync 25.02.2020 22:47

Не уверен, что это будет интересно. Использование mysqlproxy между mysql и клиентами и использование сценария lua для обновления значения ключа в memcached в соответствии с интересными изменениями таблицы UPDATE, DELETE, INSERT было решением, которое я сделал совсем недавно. Если оболочка поддерживала хуки или триггеры в php, это могло быть проще. На данный момент ни одна из оберток этого не делает.

Самым простым было бы проверить временные метки файлов таблиц на диске. Например, вы можете проверить в своем каталоге данных

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

Это должно дать вам список всех таблиц с таблицей, когда она была изменена в последний раз в самое раннее время.

Действительно отличный ответ, поскольку UPDATE_TIME имеет значение NULL для всех таблиц в моем случае (MariaDb)

Alexander Vasiljev 14.11.2018 12:16

Файлы ibd хранят только структуру таблиц. По умолчанию данные хранятся в ibdata1, поэтому временная метка файла ibd не обновляется при изменении данных в таблице. https://dev.mysql.com/doc/refman/8.0/en/show-table-status.ht‌ мл

Stack Underflow 19.05.2020 22:14

@StackUnderflow, то, что вы сказали, неточно. Файлы ibd хранят данные и индексы для табличного пространства, которое содержит одну или несколько таблиц. Если данные хранятся в ibdata1, файла ibd не будет. Хранение данных в одном файле на таблицу было по умолчанию с MySQL 5.6 в 2013 году.

Bill Karwin 20.07.2020 06:33

Анализ на уровне ОС:

Найдите, где хранится БД на диске:

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

Проверить наличие последних изменений

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

Должен работать со всеми типами баз данных.

Хотя есть общепринятый ответ, я не считаю его правильным. Это самый простой способ добиться того, что необходимо, но даже если он уже включен в InnoDB (на самом деле документы говорят вам, что вы все равно должны получить NULL ...), если вы читаете MySQL документы, даже в текущей версии (8.0) использование UPDATE_TIME является не тот вариант, потому что:

Timestamps are not persisted when the server is restarted or when the table is evicted from the InnoDB data dictionary cache.

Если я правильно понимаю (не могу проверить это на сервере прямо сейчас), метка времени сбрасывается после перезапуска сервера.

Что касается реальных (и, в общем, дорогостоящих) решений, у вас есть решение Билла Карвина с CURRENT_TIMESTAMP, и я хотел бы предложить другое, основанное на триггерах (я использую этот).

Вы начинаете с создания отдельной таблицы (или, может быть, у вас есть какая-то другая таблица, которая может использоваться для этой цели), которая будет работать как хранилище для глобальных переменных (здесь временных меток). Вам нужно сохранить два поля - имя таблицы (или любое другое значение, которое вы хотите сохранить здесь как идентификатор таблицы) и метку времени. После того, как он у вас есть, вы должны инициализировать его с этим идентификатором таблицы + датой начала (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

Я создал столбец по имени: update-at в phpMyAdmin и получил текущее время из метода Date () в моем коде (nodejs). при каждом изменении в таблице этот столбец фиксирует время изменений.

Добро пожаловать в StackOverflow! Пожалуйста, отредактируйте свой ответ, чтобы включить часть кода, который вы использовали, а также объяснение Почему, которое вы выбрали для этого. Этот вопрос почти Одиннадцать лет, и на него уже есть принятый и хорошо получивший ответ. Ваш ответ без кода или объяснения, скорее всего, будет отклонен или удален. Отредактируйте его, чтобы включить эти вещи, чтобы оправдать его место в этом посте.

Das_Geek 12.11.2019 20:13

а) Он покажет вам все таблицы и даты последнего обновления

SHOW TABLE STATUS FROM db_name;

затем вы можете дополнительно запросить конкретную таблицу:

SHOW TABLE STATUS FROM db_name like 'table_name';

б) Как и в приведенных выше примерах, вы не можете использовать сортировку по 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';

Я заставил это работать локально, но не на моем общем хосте для моего общедоступного веб-сайта (я думаю, проблема с правами).

SELECT last_update FROM mysql.innodb_table_stats WHERE table_name = 'yourTblName';

'2020-10-09 08:25:10'

MySQL 5.7.20-log on Win 8.1

Другие вопросы по теме