我有两个外部托管的第三方 .txt
文件,它们由我以外的其他人不定期更新。我已经编写了一个脚本来提取这些信息,对其进行操作,并创建一个适合在数据库中使用的合并数据数组。我不是在寻找确切的代码,而是在寻找一个好的过程的描述,该过程将有效地从该数组中插入新行(如果它尚不存在),如果任何值已更改则更新表中的行,或删除表中的一行(如果它不再存在于数据数组中)。
数据比较简单,结构如下:
map (字符串)|路线(字符串)|时间(十进制) |播放器(字符串) |国家(字符串)
map
和 route
的组合必须是唯一的。
有什么方法可以执行所有需要的操作,而不必遍历所有外部数据和我数据库中表中的所有数据?如果没有,最有效的方法是什么?
下面是我写的。它负责除删除部分以外的所有工作:
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;
}
最佳答案
您提到您正在使用 MySQL,它有一个方便的 INSERT ... ON DUPLICATE KEY UPDATE ...
语句 ( documentation here )。您将不得不遍历您的数据集合(而不是现有表)。我的处理方式与@Tim B 的处理方式略有不同...
创建 temporary table来保存新数据。
遍历新数据并将其插入新表
运行
INSERT ... ON DUPLICATE KEY UPDATE ...
语句从临时表插入到现有表中 - 它负责插入新记录和更新更改的记录。运行
DELETE FROM [existing table] t1 LEFT JOIN [temporary table] t2 ON [whatever key(s) you have] WHERE t2.id IS NULL
- 这将删除所有内容来自未出现在临时表中的现有表。
临时表的好处是它们会在连接关闭时自动删除(还有一些其他不错的功能,例如对其他连接不可见)。
此方法的另一个好处是,在步骤 1 中将数据插入表后,您可以在数据库中执行部分(或全部)数据操作。执行此类操作通常更快、更简单通过 SQL 而不是循环遍历和更改数组中的值。
关于php - 根据外部来源插入、更新或删除记录的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25810758/