基于外部源插入,更新或删除记录的正确方法是什么?

时间:2014-09-12 14:34:33

标签: php mysql sql

我有两个外部托管的第三方.txt文件,这些文件是由我以外的其他人不定期更新的。我编写了一个脚本来提取此信息,对其进行操作,并创建适合在数据库中使用的合并数据数组。我不是在寻找确切的代码,而是一个好的过程的描述,如果它不存在,将有效地从这个数组中插入一个新行,如果有任何值更改,则更新表中的行,或删除如果数据数组中不再存在该行中的一行。

数据相当简单,具有以下结构:

map (string) | route (string) | time (decimal) | player (string) | country (string)

maproute组合必须是唯一的。

有没有办法完成所有需要的操作,而无需遍历所有外部数据我数据库中表的所有数据?如果没有,那么最有效的方法是什么?

以下是我所写的内容。除了删除部分之外,它会处理所有内容:

require_once('includes/db.php');
require_once('includes/helpers.php');

$data = array_merge(
    custom_parse_func('http://example1.com/ex.txt'),
    custom_parse_func('http://example2.com/ex.txt')
);

try {

    $dsn = "mysql:host=$dbhost;dbname=mydb";
    $dbh = new PDO($dsn, $dbuser, $dbpass);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    foreach ($data as $value) {

        $s = $dbh->prepare('INSERT INTO table SET map=:map, route=:route, time=:time, player=:player, country=:country ON DUPLICATE KEY UPDATE map=:map2, route=:route2, time=:time2, player=:player2, country=:country2');

        $s->execute(array(
            ':map'      => $value['map'],
            ':route'    => $value['route'],
            ':time'     => $value['time'],
            ':player'   => $value['player'],
            ':country'  => $value['country'],
            ':map2'     => $value['map'],
            ':route2'   => $value['route'],
            ':time2'    => $value['time'],
            ':player2'  => $value['player'],
            ':country2' => $value['country']
        ));

    }

} catch(PDOException $e) {

    echo $e;

}

2 个答案:

答案 0 :(得分:2)

你提到你正在使用MySQL,它有一个方便的INSERT ... ON DUPLICATE KEY UPDATE ...语句(documentation here)。您将不得不迭代您的数据集(但不是现有的表)。我会处理它与@Tim B做的有点不同......

  1. 创建一个temporary table来保存新数据。

  2. 循环播放新数据并将其插入新表格

  3. 运行从临时表插入现有表的INSERT ... ON DUPLICATE KEY UPDATE ...语句 - 负责插入新记录和更新的更改记录。

  4. 运行DELETE FROM [existing table] t1 LEFT JOIN [temporary table] t2 ON [whatever key(s) you have] WHERE t2.id IS NULL - 这将删除现有表中未出现在临时表中的所有内容。

  5. 关于临时表的好处是它们会在连接关闭时自动删除(还有一些其他很好的功能,比如对其他连接不可见)。

    这个方法的另一个好处是,在将数据库插入到步骤1的表中之后,您可以在数据库中执行一些(或全部)数据操作。执行此类操作通常更快更简单通过SQL而不是循环并更改数组中的值。

答案 1 :(得分:1)

最简单的方法是截断表,然后插入所有值。这将满足您的所有要求。

假设这不可行,那么您需要记住哪些行已被修改,可以使用标志,版本号或时间戳来完成。例如: