通过PHP进行MySQL批量插入
在PHP中,我从URI中提取大量JSON数据,然后通过内置的通过PHP进行MySQL批量插入,php,mysql,Php,Mysql,在PHP中,我从URI中提取大量JSON数据,然后通过内置的JSON\u decode函数将其序列化到关联的PHP数组中 然后,我创建一个数组: $inserts = array(); 我在JSON关联数组中循环,为JSON数组中的每个项目向我的$inserts数组中添加一个新的键/值对: foreach($JSON_data as $key => $value) { $inserts[] = "(".mysql_real_escape_string($value["p
JSON\u decode
函数将其序列化到关联的PHP数组中
然后,我创建一个数组:
$inserts = array();
我在JSON关联数组中循环,为JSON数组中的每个项目向我的$inserts
数组中添加一个新的键/值对:
foreach($JSON_data as $key => $value) {
$inserts[] = "(".mysql_real_escape_string($value["prop1"]).","
.mysql_real_escape_string($value["prop2"]).","
.mysql_real_escape_string($value["prop3"]).")";
}
然后,我通过内爆我已经准备好的插入来执行批量插入:
mysql_query("INSERT INTO `MyTable` (`col1`,`col2`,`col3`) VALUES ".implode(",",$inserts));
无论如何,我发现不再建议使用mysql.*
系列。所以我想知道,这种类型的模式是如何通过使用准备好的语句或w/e新接受的结构来实现的?我关心的是消除SQL注入,并尽可能快地用少于10个并发的、开放的连接(最好是1个)更新MySQL。同时,要让事情尽可能简单快捷
或者,如果有新的模式或首选方法来执行此类批量事务。如果使用准备好的语句,则可以使用foreach循环遍历
$JSON_data
数组,并使用该数据块运行INSERT
使用准备好的语句将减少构建查询的开销,只需在循环的每次迭代中将新数据发送到数据库
$query = mysqli_prepare("INSERT INTO `MyTable` (`col1`,`col2`,`col3`)
VALUES(?,?,?)");
foreach($JSON_data as $key => $value) {
$query->bind_param('sss',$value["prop1"],$value["prop2"],$value["prop3"];
$query->execute();
}
请注意,bind_param()
的第一个参数告诉它将绑定多少个值,以及每个值的类型。s
对应字符串数据,i
对应整数数据,d
对应双精度浮点,b
对应二进制数据
另一个警告,不要引用任何字符串数据,因为s
数据类型告诉mysql需要一个字符串。如果在准备好的语句中引用?
,它将告诉您参数的数量是错误的。如果您引用字符串,它将在mysql中被引用
编辑:
如果您想要使用相同的范例(通过一个查询插入多行),有几种方法可以做到这一点。一种方法是创建一个类来聚合bind_参数
调用,并在执行查询时执行一个bind_参数。代码是。使用或
下面是如何利用Mysqli中准备好的语句
<?php
//Basic layout to using parametized queries in PHP to prevent Bobby-tables
$VARIABLE = "Some Data";
$mysqli = new mysqli("SERVER","USER","PASSWORD","DATABASE");
$query = $mysqli->prepare("SELECT COLUMN_LIST FROM TABLE WHERE COLUMN = ?");
$query->bind_param('s',$VARIABLE); //'s' for string, use i for int d for double
$query->execute();
//Get results
$query->bind_result($VARIABLE_NAMES_MATCHING_COLUMN_NAMES_GO_HERE);
$query->fetch();
echo $VARIABLE_LIST_MATCHING_COLUMN_LIST;
?>
该块是否会在循环的每次迭代中阻塞?如果是这样的话,这会不会比单个查询花费更长的时间来完成(因为迭代次数接近一个很高的数字)?我不确定它是否会阻塞,但是如果你想使用多个值()
列表,有一个类可以帮你做到这一点。只需使用循环或str_repeat()
准备语句,然后在循环中使用mbind_param()
,并延迟调用execute()
,直到循环完成。这是最好的答案,但我决定采用另一种方法,使用注释过的LOAD DATA infle
。@gcochard我认为即使使用链接到此处的类以及准备好的语句,也不能用一个查询插入多行。正如您所说,它将值和类型附加在一起。但要插入它们,您必须在准备好的语句(即nRows*N列)中包含相同数量的“?”。我尝试使用这个类并一次插入多行,但得到了以下警告:PHP警告:mysqli_stmt::bind_param():变量的数量与prepared语句中的参数数量不匹配,因为我不清楚如何模仿这个。啊,我的错误。看来@Greg已经完全回答了上面的问题。顺便说一句,如果你想要真正快速的插入LOAD DATA infle
很难打败。不过,我不建议在您的情况下使用它(如果您将数据作为JSON提取,那么它可能没有那么大),但是如果您需要同时向MySQL插入许多兆字节/千兆字节,请记住这一点。我修改了下面提到的类,在一个查询中插入多行(execute语句)。