2012-10-18 142 views
3

在PHP中,我從URI中提取大量JSON數據,然後通過內置的json_decode函數將其序列化爲關聯的PHP數組。通過PHP批量插入MySQL

然後,創建一個磁盤陣列:通過JSON關聯數組

$inserts = array(); 

我循環,增加一個新的鍵/值對我$inserts陣列JSON數組中的每一項:

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)); 

然後,我簡單地通過內爆我已經制備的插入執行批量插入10

無論如何,我發現不再建議使用mysql_*家族。所以我想知道這種類型的模式是如何用預先準備好的語句來完成的,還是使用新的可接受的結構?我的顧慮是消除SQL注入,並且儘可能快地將MySQL更新爲,同時打開少於10個連接(最好是1個)。此外,要儘可能簡單快捷。

或者,如果有新模式或首選方法來執行這種批量交易。

+2

順便說一句,如果你想真的* *快速插入'LOAD DATA INFILE'是很難被擊敗。雖然我不會在你的情況下提出這個建議(除了其他任何東西,如果你將數據作爲JSON提取,它可能不會那麼大),但是值得注意的是,如果你需要在MySQL中插入許多兆字節/千兆字節,一旦。 –

+0

請參閱http://pastebin.com/28cSmi2C。我修改了下面提到的類來在一個查詢中插入多行(執行語句)。 – whitewalker

回答

5

如果您使用準備好的語句,則可以使用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_param調用,並在執行查詢時執行一個bind_param。代碼是here

+0

這個塊在循環的每次迭代中都有效嗎?如果是這樣,那麼這會不會使得完成比單個查詢更長的時間(因爲迭代次數接近高數)? – user17753

+0

我不確定它是否會阻止,但如果你想使用多個'VALUES()'列表,那麼有一個類[here](http://www.php.net/manual/en/mysqli-stmt) .bind-param.php#110363)這將幫助你做到這一點。只需用循環或'str_repeat()'準備語句,然後在循環中使用'mbind_param()',並延遲調用'execute()'直到循環結束。 – gcochard

+0

這是最好的答案,但我決定採用不同的方法,使用被評論過的'LOAD DATA INFILE'。 – user17753

1

使用MysqliPDO

這裏是你將如何利用準備好的語句與庫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; 

?> 
+0

這並沒有完全回答這個問題,因爲我不清楚如何模仿[這種類型的結構](http:// stackoverflow.com/questions/10635414/how-to-insert-bulk-data-into-database-at-a-time)。 – user17753

+0

啊我的錯誤。看起來@Greg已經完全回答了。 – BOMEz