【问题标题】:MySQL: Check If Table's Data Has modified Without trigger and UDF?MySQL:检查表的数据是否在没有触发器和 UDF 的情况下修改?
【发布时间】:2013-06-03 01:48:52
【问题描述】:

有没有办法知道 MySQL 表的数据是否被修改?

【问题讨论】:

标签: php mysql sql


【解决方案1】:

您可以查询INFORMATION_SCHEMA 数据库,表TABLES 并且有一列“UPDATE_TIME”。 (SHOW TABLES 有点等价)。

另一种方法是让 PHP 访问 db 文件(如果可以找到它们)并检查文件修改的系统日期。 EDIT 读取权限足以完成此操作。

【讨论】:

  • 不错的答案 +1(至少是第一部分;)我不确定 PHP 是否应该有权访问 db 文件。
  • 如果您授予 PHP 访问权限,它以 root/管理员等身份运行。要查看要查看的文件,例如。 this thread。这当然是一些解决方法;我不确定SHOW TABLES 是否在每个数据库引擎中都有 UPDATE_TIME 字段。
  • 不,我只是想指出,让 php 访问文件可能是一个潜在的风险。但是,information_schema 应该很适合。 (不知道更新时间保存在那里,谢谢)
  • 是的,我同意,感谢您指出这一点,但是——正如我在 EDIT 中所说——您可以授予 PHP 只读权限。如果您查看two last comments on MySQL page,这可能不适用于 InnoDB。
  • 是的,如果拥有读取权限,则可以通过 php.ini 中的潜在错误访问无法使用 mysql 权限系统访问的数据。 :)
【解决方案2】:

在与@Voitcus 聊天时,我们发现information_schema 方法不适用于InnoDb 表。对于此类表,UPDATE_TIME 列将是 NULL

这就是为什么我们为InnoDB 表制定了一个不需要对硬盘上的 db 文件进行读取访问的解决方案(我认为这是一个安全问题,没有管理员应该允许这样做,db 服务器也可以是在不同的主机上)

解决方案:

正如您所说,您不能为此使用触发器函数,您必须在 PHP 中的应用程序级别修复此问题。 更新:请注意,对于当前版本的 MySQL,无论如何使用触发器都不稳定,因为它们不会被级联外键操作调用。

首先创建一个表,比如说stats

CREATE TABLE `yourdb`.`stats` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `table_name` VARCHAR( 255 ) NOT NULL ,
    `last_update` DATETIME NOT NULL
) ENGINE = InnoDB;

为应用程序中的每个表插入一行。

在 PHP 中修改现有查询,以便它们使用事务并更新统计表。例如,这可以使用 mysqliPDO。我这里用的是PDO,比如我们删除一行。

try {
    $pdo = new PDO($host, $user, $pass, $db, array((
        // this option is nice when working with transactions
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ));
} catch (PDOException $e) {
    die('cannot connect to mysql');
}


try {
    // start transaction
    $pdo->beginTransaction();
    // delete a row
    $pdo->query('DELETE FROM `table1` WHERE `id` = 1');
    // update stats
    $pdo->query('UPDATE `stats` SET `last_update` = NOW() WHERE `table_name` = `table1`');
    // commit both queries at once
    $pdo->commit();
} catch (Exception $e) {
    // rollback both queries if one of them failed
    $pdo->rollback();
}

现在您可以使用以下查询来获取上次更新时间:

SELECT `last_updated` FROM `stats` WHERE `table_name` = 'table1'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多