2015-11-13 3 views
0

Как лучше всего добавить строку базы данных multiInsert?
Например, у меня есть массив, и я бы хотел добавить весь массив в базу данных. Я могу создать цикл foreach и добавить все массивы.Лучший способ multiInsert для добавления базы данных в php?

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

И это работа, но возможно я должен использовать транзакцию? или иначе?

ответ

1

Используйте подготовленное заявление.

$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 (?), (?), (?), ... 

, где есть так много (?) как число элементов в $array.

Выполнение одного запроса с большим количеством 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)); 
+0

Ya, я знаю, подготовленно. Вы говорите это лучше, так как добавьте массив в цикле? – Pekus

+0

Дело в том, чтобы сделать один запрос вместо многих запросов. – Barmar

+0

Хорошо, спасибо, но у меня есть одна проблема. Почему он не работает? $ column = implode (',', array_keys ($ array)); $ val = implode (',', ''. Array_values ​​($ array. '')); $ sql = "INSERT INTO test ($ column) VALUES ('$ val')"; – Pekus

1

, как вы сделали это, во многих отношениях, худший вариант , Поэтому хорошая новость заключается в том, что любой другой способ сделать это, вероятно, будет лучше. Как бы то ни было, код может выйти из строя в зависимости от того, что находится в данных; рассмотрите:

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

Но, не зная, каковы ваши критерии для «наилучшего», его довольно сложно посоветовать. Использование параметризованного запроса с привязкой данных или, как они часто описываются, «подготовленные заявления» - одно из решений проблемы, описанной выше. Эквивалентное значение , прежде чем интерполировать строку, является другой (и как большинство реализаций реализации данных в PHP за кадром) является еще одним распространенным решением.

Оставляя в стороне вопрос о том, как вы получаете параметры в инструкции SQL, возникает вопрос о производительности. Каждая поездка в базу данных имеет стоимость, связанная с ней. И одновременное выполнение одной вставки также влияет на производительность. Для каждого запроса СУБД должен анализировать запрос, применять соответствующие элементы управления параллелизмом, выполнять запрос, применять записи в журнале, затем к таблицам данных и индексам, затем убирать, прежде чем он сможет вернуть поток выполнения обратно в PHP, чтобы построить следующий запрос.

Обертка нескольких запросов в транзакции (вы уже используете транзакции, но они неявны и применяются к каждому оператору) могут уменьшить некоторые из накладных расходов, которые я описал здесь, но могут вводить другие проблемы, характер которых зависит от которая использует модель параллелизма, используемую вашей СУБД.

Чтобы получить данные в базу данных как можно быстрее, и свести к минимуму фрагментации индекса, «лучший» решение для пакетной до нескольких вставок:

$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, но я думаю, проще понять, когда вы работаете с более сложными структурами записей, и он не будет разбиваться на очень большие входные наборы.

+0

он использует PDO, а не mysqli. – Barmar

+0

Не указано как требование. – symcbean

+0

Его код использует PDO, и он находится в тегах. – Barmar

Смежные вопросы