如何使用PHP将大文件插入MySQL数据库?

9
我要上传最大为10MB的大文件到我的MySQL数据库。使用 .htaccess 更改了PHP本身的文件上传限制为“10485760”= 10MB。我能够上传大小不超过10MB的文件,没有任何问题。
但是如果文件的大小超过1MB,我无法将其插入数据库。 我正在使用 file_get_contents 来读取所有文件数据,并将其作为字符串传递给插入查询以插入LONGBLOB字段。
但是大于1MB的文件无法添加到数据库中,尽管我可以使用 print_r($ _FILES)确保文件被正确上传。 非常感谢您的帮助,我需要在接下来的6个小时内解决此问题,请尽快提供帮助!

在使用mysql_error()时,我遇到了一个2.83M文件的错误 - “MySQL服务器已断开连接”,是否有任何方法可以在我的共享托管站点上更改数据包大小?例如向某些文件添加变量声明? - anjan
7个回答

15
您需要检查MySQL配置值"max_allowed_packet",它可能设置得太小,导致无法执行大型的INSERT操作。请从mysql命令提示符下运行以下命令:
mysql> show variables like 'max_allowed_packet';

确保它足够大。有关此配置选项的更多信息,请参见

MySQL max_allowed_packet

这也会影响 PHP 中的 mysql_escape_string() 和 mysql_real_escape_string(),限制字符串创建的大小。


8
据我所知,通常最好不要将文件存储在数据库中,因为这样会使数据库变得非常庞大并且减慢速度。最好的方法是创建一个目录来存储文件,然后只在数据库中存储文件位置。我们在工作中的CMS中对于图片/ PDF / mpeg等文件都是这样做的,通过创建以url安全文件名命名的文件夹来存储文件,并将文件夹名称存储在数据库中。在表示层只需编写其URL即可。

1
我终于不得不承认,在我的当前项目中将较大的文件放入数据库是一个很大的麻烦,所以我将文件上传到目录中并保存路径在数据库中。但仍然对数据库存储感到好奇。 - anjan
1
这里也是同样的情况,我们不得不改用文件系统。(数据库维护变得太慢/痛苦了) - Jacco
2
这通常适用于mysql,因为blob不是真正的blob,而是限制在4GB(对于longblob)。真正的DBMS(Oracle、MSSQL、Firebird)没有这个限制,也不会减慢速度。当所有内容都在单个数据库中时,处理备份和恢复要容易得多。无论如何,如果你被困在MySQL中,可以使用mysqli_stmt_send_long_data以块的形式流式传输大文件。 - Milan Babuškov
5
我尝试使用文件系统存储数据。但是我发现,保持数据库与文件系统同步是额外的麻烦。如果有人在文件系统中删除了一个文件会怎样?如果数据库记录被删除但相关联的文件仍然存在于文件系统中又该如何处理?当涉及到数据库外的因素时,要使数据库操作具有原子性变得很复杂。 - Rolf
1
将文件存储在文件系统中而不是数据库中并不是“更好的做法”。这只是一种不同的方法。有许多有效的理由可以解释为什么你应该将文件存储在数据库中,例如可移植性等。令人难以置信的是,“不要将文件存储在数据库中”的这种说法已经广泛传播,包括这种做法会使系统更快的假设。 - Rid Iculous
@RidIculous 说实话,我使用了AFAIK限定词:) 我们谈论的是MySQL,在这里,大多数人将运行的典型设置并未针对存储文件进行优化。可能这就是谣言的来源。我肯定不是一个DBA,也不确定如何从数据库在线流/链接图像,因此我发现这种方法更易于理解和使用。 - roborourke

4
一些用于MySQL的PHP扩展存在LONGBLOB和LONGTEXT数据类型的问题。这些扩展可能不支持流式传输blob(将blob分段发送),因此必须一次性发送整个对象。因此,如果PHP的内存限制或MySQL的数据包大小限制限制了可以发布到数据库的对象的大小,则可能需要在PHP或MySQL上更改一些配置以允许此操作。
您没有说明使用哪个PHP扩展(MySQL至少有三个),也没有显示将blob发布到数据库的任何代码。

4
最好的解决方法是使用一个更好的实现,并且解决这个问题。您可以在这里阅读一篇文章。无论是存储10MB还是1000MB都没有关系,这个实现将文件切成许多较小的部分并将它们存储在多个行中。这有助于负载和获取,因此内存也不会成为问题。

3
你可以使用MySQL的LOAD_FILE函数来存储文件,但你仍然需要遵守max_allowed_packet值和文件必须在MySQL实例所在的同一台服务器上的事实。

0
你没有说明你遇到了什么错误(使用 mysql_error() 命令来查找),但我怀疑你可能是因为达到了 MySQL 最大数据包大小限制。

如果是这种情况,你需要更改 MySQL 配置中的 max_allowed_packet。

嗯,我也遇到了同样的问题。在“io模式”下无法逐块输入数据到 MySQL 数据库中。

loop for : 
   read $data from file,
   write $data to blob
end loop
close file
close blob

一个解决方案似乎是创建一个带有多部分二进制大对象的表,例如 创建数据详情表 ( id int 主键 自增, 块编号 int 非空, 数据部分 二进制大对象 ); ???


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接