Есть ли способ вставить большое значение в БД mysql без изменения max_allowed_packet? - PullRequest
6 голосов
/ 20 сентября 2010

Я знаю, что для вставки значений, превышающих max_allowed_packet байт, в базу данных MySQL, решением по умолчанию было бы гарантировать, что max_allowed_packet переменные как на стороне клиента, так и на стороне сервера больше, чем порция данных, которую вставляет запросв БД.

Однако, есть ли способ сделать это без изменения упомянутой выше переменной на стороне сервера?Это было бы полезно, когда мне нужно было вставить данные в базу данных, размещенную на интернет-провайдере, которая не позволяет мне изменить ограничение max_allowed_packet.

Другой связанный с этим вопрос: ограничение MySql longblob составляет 4 ГБ, но ограничение max_allowed_packet составляет 1 ГБ.Итак, возможно ли вставить значения больше 1 ГБ в столбец таблицы longblob?

Ответы [ 2 ]

11 голосов
/ 31 января 2011

Я недавно наткнулся на эту проблему. В моем случае max_allowed_packet сервера был 1 МБ, и я ничего не мог сделать, чтобы изменить его. И я вставлял некоторые данные чуть больше 1 МБ. Я нашел два варианта решения.

1) Во-первых, используя JDBC. Поскольку MySQL Connector / J v3.1.9 , есть несколько параметров, которые вы можете установить, вот мой набор параметров в URL JDBC:

Добавить эти:

blobSendChunkSize=50000&useServerPrepStmts=true&emulateUnsupportedPstmts=false&maxAllowedPacket=20000000

В результате URL JDBC:

jdbc:mysql://serverip:3306/databasename?noDatetimeStringSync=true&blobSendChunkSize=50000&useServerPrepStmts=true&emulateUnsupportedPstmts=false&maxAllowedPacket=20000000

Затем вы должны использовать PreparedStatement для вставки и использовать InputStream для передачи содержимого байта в качестве параметра в setObject. Обратите внимание, что setObject с использованием байтовых массивов не разрешит разбиение BLOB-объектов. Комбинация параметров, недавний сервер MySQL (5.0.45 или новее) и InputStream будут отправлять данные большого двоичного объекта с использованием механизма LONG DATA, разбивая большой двоичный объект в соответствии с blobSendChunkSize.

Решение JDBC работает, и я проверил его.

2) Теперь второй вариант - использовать драйвер PHP mysqli и mysqli_send_long_data. Для вашего удобства скопирован из PHP пример с примером:

<?php
$stmt = $mysqli->prepare("INSERT INTO messages (message) VALUES (?)");
$null = NULL;
$stmt->bind_param("b", $null);
$fp = fopen("messages.txt", "r");
while (!feof($fp)) {
    $stmt->send_long_data(0, fread($fp, 8192));
}
fclose($fp);
$stmt->execute();
?>
0 голосов
/ 20 сентября 2010

Я не думаю, что есть способ. Может быть, расколотая капля добьется цели.

Но я думаю, что чтение этой статьи http://blogs.msdn.com/b/oldnewthing/archive/2007/03/01/1775759.aspx от Реймонда Чена - лучший ответ на ваш вопрос.

Реляционные базы данных не предназначены для такого использования. Если вам нужно хранить гигабайт + большой двоичный объект в базе данных, лучше обычно хранить его в NFS и просто иметь короткую строку расположения файла в вашей БД. Избавит вас от многих неприятностей в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...