在mysql中使用时间戳条件将数据插入一个表中,从另一个表中删除

时间:2014-12-01 10:13:55

标签: php mysql performance time pdo

简而言之

是否有安全方法将数据库条目(基于时间戳条件)移动到另一个表(没有先查询时间)?为确保这一点,INSERT INTODELETE完全相同的条目工作?

问题的背景

  • 这个问题不是关于使用交易的重要性,这是给定的!但是,对于两个后续查询,时间(例如NOW()的值可能会有所不同这个问题。
  • 由于使用了一个编程框架(出于安全原因)不允许在一次调用中执行多个查询,因此 确实
  • 成为一个问题

示例表结构

Source
---------------------------------------------
ID        |  Timeout              |  Data
---------------------------------------------
1         |  2014-12-31 12:00:00  |  foo
2         |  2014-12-31 15:00:00  |  bar
3         |  2014-12-31 18:00:00  |  foobar

Archive
---------------------------------------------
ID        |  Data
---------------------------------------------

示范(简化)

<?php

    beginTransaction();
    try {
        // Imagine this happens at 2014-12-31 14:59:59(.992) [Entry #2 not copied]
        execute( "INSERT INTO Archive (ID, Data) 
                      SELECT ID, Data FROM Source
                      WHERE Timeout <= NOW()" );

        // While here it might be already 2014-12-31 15:00:00(.004) [Entry #2 deleted]
        execute("DELTE FROM Source WHERE Timeout <= NOW()");
        commit();
    }
    catch (Exception $e) {
        rollBack();
        return false;
    }

    return;
?>

因此有一种安全方式可以避免这个问题,最好还是性能 (我知道,在这种情况下,php可能是首先是错误的语言^^)。非常感谢!

1 个答案:

答案 0 :(得分:1)

execute("SET @now = NOW()");

execute("
    INSERT INTO Archive (ID, Data) 
    SELECT ID, Data 
    FROM Source
    WHERE Timeout <= @now
");

execute("DELTE FROM Source WHERE Timeout <= @now");

OR

execute("
    INSERT INTO Archive (ID, Data) 
    SELECT ID, Data 
    FROM Source
    WHERE Timeout <= NOW()
");

execute("DELTE FROM Source WHERE Timeout <= (SELECT MAX(Timeout) FROM Archive)");