我正在编写一个脚本,其中我想将 8000+ 行从一个表传输到另一个数据库中具有选定列的另一个表。到目前为止,我已经考虑使用 PDOStatement::fetchAll()
作为$result
数组来获取整个源表的选定列,然后使用PDO::prepare()
方法准备一个 mySQL 插入语句
INSERT INTO targetTable (targetColumn1,targetColumn2...) VALUES
(sourceRow1ForColumn1,sourceRow1ForColumn2,..),
(sourceRow2ForColumn1,sourceRow2ForColumn2,..),
(sourceRow3ForColumn1,sourceRow3ForColumn2,...),...
但我认为这不是一种有效的方法,应该有一个最佳的方式来做我想做的事情。有没有更好的方法可以做我想做的事情?
执行此操作的最佳方法是使用 插入...选择语句。
INSERT INTO targetTable (targetColumn1,targetColumn2)
SELECT expr1, expr2 FROM one_table
expr1
和 expr2
表示分别返回要插入到targetColumn1
列和targetColumn2
列中的值的表达式。
表达式可以是对源表中列名称的简单引用。
如果表位于同一 MySQL 实例上的不同数据库(架构)中,则可以使用数据库名称限定表名。(非限定表名是指当前数据库中的表(即 USE mydatabase)。
如果当前数据库是目标数据库,请在 FROM 子句中限定名称表
INSERT INTO targetTable (targetColumn1,targetColumn2)
SELECT expr1, expr2 FROM anotherdb.one_table
^^^^^^^^^^
如果当前数据库包含源表,请限定目标表的名称。
或者只是限定两个表名,哪个数据库是最新的并不重要。
只需以对每个表具有足够权限的用户身份连接到 MySQL。
GRANT SELECT ON anotherdb.one_table TO myuser@'%';
GRANT INSERT ON targetdb.targetTable TO myuser@'%';
如果插入尝试
插入违反目标表中唯一约束的行,则 INSERT 也会发生同样的事情......选择,就像插入...价值观声明...语句将失败。
如果您想忽略有关重复项的错误,而只是跳过这些行,请使用插入忽略...选择属性。 (IGNORE 关键字会导致 MySQL 不会跳过该行,而不是在违反唯一键约束时抛出错误。
或者,您可以编写 SELECT 语句来排除目标表中已存在的行。
如果要做一次,你不需要关心性能。
把 set_time_limit(0); 放在 PHP 文件的开头。
然后,连接到您的第一个数据库。 从源表中读取数据并存储在数组中。
现在,断开连接并连接到新数据库,并将数组数据插入目标表
为了处理重复键,您可以在查询中使用"重复时插入"或"更新"。
如果您的记录很大,则内存可能有问题。因此,最好在存储到数组之前获取计数。然后,在一个循环中执行该过程,在每个循环结束时,通过 unset() 释放数组。因此,您拆分记录并以适当的方式保持内存使用。