Как лучше всего добавить строку базы данных multiInsert?
Например, у меня есть массив, и я бы хотел добавить весь массив в базу данных. Я могу создать цикл foreach и добавить все массивы.
$array=['apple','orange']; foreach($array as $v) { $stmt = $db->exec("Insert into test(fruit) VALUES ('$v')"); }
И это работа, но, может быть, я должен использовать транзакцию? или иначе?
Используйте подготовленное заявление.
$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));
То, как вы это сделали, во многих отношениях является худшим вариантом. Поэтому хорошая новость заключается в том, что любой другой способ сделать это, вероятно, будет лучше. Как бы то ни было, код может выйти из строя в зависимости от того, что находится в данных; рассматривать:
$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); }
Это похоже на метод Бармара, но я думаю, что легче понять, когда вы работаете с более сложными структурами записей, и он не сломается с очень большими наборами ввода.