MySQL 테이블이 마지막으로 업데이트 된 시점을 어떻게 알 수 있습니까?


176

내 페이지의 바닥 글에 "my / 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 statususes information_schema.tables)
KCD

11
아래 의 UPDATE_TIME방법과 show table status방법은 모두 InnoDB가 아닌 MyISAM 엔진에서만 사용할 수 있습니다. 이것은 버그 로 나열되어 있지만 , MySQL 5.5 Reference에 언급되어 있으며 ,이 file_per_table모드는 모드가 신뢰할 수없는 수정 시간의 지표 라고 말합니다 .
idoimaging

5
mysql이 버그가 있기 때문에 InnoDB에서도 작동하지 않습니다. bugs.mysql.com/bug.php?id=14374
TMS

7
MySQL 5.7.2+의 경우 InnoDB 에서도 작동합니다 . "MySQL 5.7.2부터 UPDATE_TIME은 분할되지 않은 InnoDB 테이블에서 수행 된 마지막 UPDATE, INSERT 또는 DELETE에 대한 타임 스탬프 값을 표시합니다. 이전에는 UPDATE_TIME에 NULL 값이 표시되었습니다. "InnoDB 테이블의 경우"
Peter V. Mørch

2
이것은 나를 위해 다시 시작해도 지속되지 않는 것 같습니다 (버전 5.7.11).

58

mysql 버전 4.1.16을 사용하는 information_schema 데이터베이스가 없으므로이 경우 다음을 쿼리 할 수 ​​있습니다.

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

다음과 같은 열을 반환합니다.

| 이름 | 엔진 | 버전 | Row_format | 행 | Avg_row_length 
| 데이터 길이 | Max_data_length | Index_length | Data_free | 자동 증분
| Create_time | 업데이트 _ 시간 | Check_time | 콜 레이션
| 체크섬 | Create_options | 코멘트 |

"당신은라는 열이 볼 수 있듯이 UPDATE_TIME "에 대한 마지막 업데이트 시간을 보여줍니다 당신에게 your_table가 .


2
또한 SELECT 문보다 빠르다 (4 배)
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 |
+---------------------+

물론, 더 많은 스토리지가 필요합니다 (TIMESTAMP의 경우 행당 4 바이트).
그러나 이것은 5.7.15 버전의 MySQL 이전의 InnoDB 테이블에서는 작동 하지만 INFORMATION_SCHEMA.TABLES.UPDATE_TIME그렇지 않습니다.


10
+1 내가 아는 한, 이것은이 질문에 대한 정답입니다. 질문은 사용자와 관련이없는 테이블이 어떤 이유로 든 변경되거나 변경되지 않았을 때가 아니라 관련 데이터가 업데이트되는 시점을 실제로 알고 싶어합니다.
siride

23
그러나 업데이트 시간이 짧은 레코드를 삭제하면 MAX (updated_at)가 작동하지 않습니다.
Ammamon

3
@Ammamon, 사실, 삭제를 설명 해야하는 경우이 솔루션에는 해당 내용이 반영되지 않습니다. 요약 테이블을 업데이트하는 트리거가 유일한 포괄적 인 솔루션 일 수 있지만 병목 현상이 발생합니다.
Bill Karwin

2
대부분의 경우 삭제를 아는 것은 관련성이 없으며 많은 상위 레벨 aps는 실제로 많은 테이블에서 삭제하지 않고 단순히 해당 플래그를 설정 해제합니다.
Samuel Fullman

1
@ Pavan, 차이점은 없습니다. 기본 동작에만 의존하고 있으며 예제는 옵션을 명시 적으로 설명합니다. 그러나 옵션은 기본 동작과 동일합니다.
Bill Karwin

13

가장 간단한 방법은 디스크에서 테이블 파일의 타임 스탬프를 확인하는 것입니다. 예를 들어, 데이터 디렉토리에서 확인할 수 있습니다

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

먼저 가장 오래된 시간에 테이블을 수정했을 때 테이블이있는 모든 테이블의 목록을 제공해야합니다.


내 (MariaDb) 경우의 모든 테이블에 대해 UPDATE_TIME 이후 NULL이됩니다.
Alexander Vasiljev

ibd 파일은 테이블 구조 만 저장합니다. 기본적으로 데이터는 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가 null입니까? 어떤 생각?
Metafaniel

5
MyISAM 대신 InnoDB를 사용하고 있기 때문에 UPDATE_TIME은 null입니다. InnoDB가 일반적으로 더 나은 선택이지만 UPDATE_TIME을 지원하지 않습니다.
Xaraxia

5

모든 업데이트 / 삽입 / 삭제를 포착하고 사용자 정의 테이블에 타임 스탬프를 쓰는 트리거를 작성합니다. tablename | 타임 스탬프

db 서버의 내부 시스템 테이블을 직접 읽는 아이디어가 마음에 들지 않기 때문에


1
UPDATE_TIMEMySQL과 같은 열 이 없기 때문에 이것은 MS SQL에 대한 좋은 솔루션처럼 보입니다 .
Darcy

3

인정되는 대답이 있지만 그것이 옳다고 생각하지 않습니다. 필요한 것을 달성하는 가장 간단한 방법이지만, InnoDB에서 이미 활성화되어 있어도 (실제로 문서는 여전히 NULL을 가져야한다고 알려줍니다 ...), UPDATE_TIME을 사용하여 현재 버전 (8.0)에서도 MySQL docs 를 읽는 경우 올바른 옵션이 아닙니다.

서버가 다시 시작되거나 InnoDB 데이터 사전 캐시에서 테이블이 제거 될 때 타임 스탬프가 유지되지 않습니다.

올바르게 이해하면 (지금 서버에서 확인할 수 없음) 서버가 다시 시작된 후 타임 스탬프가 재설정됩니다.

실제 (그리고 비용이 많이 드는) 솔루션에 대해서는 CURRENT_TIMESTAMP를 사용하는 Bill Karwin의 솔루션 이 있으며 트리거를 기반으로 다른 솔루션 을 제안하고 싶습니다 (저는 그 중 하나를 사용하고 있습니다).

전역 변수 (여기서 타임 스탬프)의 저장소처럼 작동하는 별도의 테이블을 만들거나 (이 목적에 사용할 수있는 다른 테이블이있을 수도 있습니다) 시작합니다. 테이블 이름 (또는 여기에 테이블 ID로 유지하려는 값)과 타임 스탬프의 두 필드를 저장해야합니다. 그것을 가지고 나면이 테이블 id + 시작 날짜 (NOW ()는 좋은 선택 :))로 초기화해야합니다.

이제 다음과 같은 절차를 사용하여 관찰하려는 테이블로 이동하고 트리거 삽입 / 업데이트 / 삭제 후 트리거를 추가합니다.

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
외모는 매우 비 휴대용 해킹, 더 나은 것 모든 곳에서 일하는 것이 표준 방법을 좋아한다
Tejesh Alimilli에게

0

Linux를 실행중인 경우 inotify를 사용하여 테이블 또는 데이터베이스 디렉토리를 볼 수 있습니다. inotify는 PHP, node.js, perl에서 구할 수 있으며 대부분의 다른 언어를 의심합니다. 물론 inotify를 설치했거나 ISP에 설치해야합니다. 많은 ISP는 그렇지 않습니다.


2
데이터베이스가 별도의 서버에서 실행중인 경우 파일 시스템 검사가 유용하지 않습니다
Sam Dufel

0

이것이 관심이 있는지 확실하지 않습니다. mysql과 클라이언트간에 mysqlproxy를 사용하고 흥미로운 테이블 변경 사항에 따라 meacached의 키 값을 업데이트하기 위해 lua 스크립트를 사용하면 UPDATE, DELETE, INSERT가 내가 최근에 해낸 솔루션이었습니다. 래퍼가 PHP에서 후크 또는 트리거를 지원하는 경우 이는 더 쉬울 수 있습니다. 현재 래퍼 중 아무것도이 작업을 수행하지 않습니다.


0

phpMyAdmin에서 update-at이라는 이름으로 열을 만들고 내 코드 (nodejs)의 Date () 메서드에서 현재 시간을 얻었습니다. 테이블을 변경할 때마다이 열에는 변경 시간이 포함됩니다.


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.