我知道为了将大于max_allowed_packet
字节的值插入MySQL数据库,默认解决方案是确保客户端和服务器端max_allowed_packet
变量都大于数据块查询插入数据库。
但是,有没有办法没有更改上面提到的服务器端变量?当我必须将数据插入托管在ISP中且不允许我更改max_allowed_packet
限制的数据库时,这将非常有用。
另一个相关问题:MySql longblob
限制为4GB,但max_allowed_packet
限制为1GB。那么,是否可以在longblob
表列中插入大于1GB的值?
答案 0 :(得分:11)
我最近偶然发现了这个问题。在我的情况下,服务器的max_allowed_packet
是1 MB,我无法改变它。我正在插入一些超过1 MB的数据。我找到了两个候选解决方案。
1)首先,使用JDBC。 从 MySQL Connector / J v3.1.9 开始,您可以设置一些参数,这是我在JDBC URL中的参数集:
附加以下内容:
blobSendChunkSize=50000&useServerPrepStmts=true&emulateUnsupportedPstmts=false&maxAllowedPacket=20000000
导致JDBC URL:
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
机制发送blob数据,根据blobSendChunkSize
拆分blob。
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();
?>
答案 1 :(得分:-1)
我认为没有办法。也许拆分blob就可以了。
但我认为阅读Reymond Chen的这篇文章http://blogs.msdn.com/b/oldnewthing/archive/2007/03/01/1775759.aspx是你问题的最佳答案。
关系数据库不是为这种用途而设计的。如果你需要在数据库中存储一个千兆字节+ blob,那么通常最好将它存储在NFS上,并在数据库中只有一个短文件位置字符串。将为您节省很多麻烦。