在php中添加数据库的最佳multiInsert方式


Best multiInsert way to add database in php?

添加到数据库multiInsert行的最佳方式是什么
例如,我有数组,我想把所有数组都添加到数据库中。我可以创建循环foreach并添加所有数组。

 $array=['apple','orange'];
 foreach($array as $v) 
 {
   $stmt = $db->exec("Insert into test(fruit) VALUES ('$v')");
 }

这是工作,但也许我应该使用transaction?还是其他方式?

使用准备好的语句。

$sql = "INSERT INTO test (fruit) VALUES ";
$sql .= implode(', ', array_fill(0, count($array), '(?)'));
$stmt = $db->prepare($sql);
$stmt->execute($array);

SQL看起来像:

INSERT INTO test (fuit) VALUES (?), (?), (?), ...

其中CCD_ 1的数量与CCD_。

使用多个VALUES执行单个查询比在循环中执行单独的查询效率高得多。

如果您有一个包含单行输入值的关联数组,那么您可以使用这样一个准备好的查询:

$columns = implode(',', array_keys($array);
$placeholders = implode(', ', array_fill(0, count($array), '?'));
$sql = "INSERT INTO test($columns) VALUES ($placeholders)";
$stmt = $db->prepare($sql);
$stmt->execute(array_values($array));

从很多方面来说,你这样做是最糟糕的选择。因此,好消息是,任何其他方式都可能会更好。目前,代码可能会失败,这取决于数据中的内容;考虑:

$v="single ' quote";
$stmt = $db->exec("Insert into test(fruit) VALUES ('$v')");

但如果不知道你的"最佳"标准是什么,就很难给出建议。使用带有数据绑定的参数化查询,或者通常被称为"准备好的语句",是解决上述问题的一种方法。在插入字符串之前适当地转义是另一种常见的解决方案(这也是大多数PHP数据绑定实现在幕后工作的方式)。

抛开如何将参数输入SQL语句的问题不谈,还有性能问题。数据库的每一次往返都有相关的成本。一次插入一次也会对性能产生影响-对于每个查询,DBMS必须解析查询,应用适当的并发控制,执行查询,将写入应用于日志,然后对数据表和索引进行整理,然后将执行线程返回给PHP以构建下一个查询。

将多个查询封装在一个事务中(您已经在使用事务了,但它们是隐式的,并应用于每条语句)可以减少我在这里描述的一些开销,但也会引入其他问题,其性质取决于DBMS使用的并发模型。

为了尽快将数据放入数据库,并最大限度地减少索引碎片,"最佳"解决方案是批量处理多个插入:

$q="INSERT INTO test (fruit) VALUES ";
while (count($array)) {
    $s=$q;
    $j='';
    for ($x=0; $x<count($array) && $x<CHUNKSIZE; $x++) {
         $s.=$j." ('" . mysqli_real_escape_string($db,
            array_shift($array)) . "')";
         $j=',';
    }
    mysqli_query($db,$s);
}

这与Barmar的方法类似,但我认为当您使用更复杂的记录结构时更容易理解,而且它不会在非常大的输入集中崩溃。