从 PHP GD 图像对象将图像存储到数据库的有效方法
我需要生成大量小型 (1-10KB) PNG 图像(>1000 万)并将其存储到数据库中。 我唯一关心的是图像/秒吞吐量。目前我知道将GD图像对象存储到数据库的两种方法:
使用输出缓冲区:
ob_start();
imagepng($image);
$imageData = ob_get_contents();
ob_end_clean();
使用临时文件(tmpfs/ramfs):
$tmpFilePath = '/dev/shm/file_000.png';
imagepng($image, $tmpFilePath);
$imageData = file_get_contents($thumbnail);
更新。还有第三种方法:使用 PHP 内存流:
// PHP streams are NOT supported
$tmpFilePath = 'php://memory';
imagepng($image, $tmpFilePath);
$imageData = file_get_contents($tmpFilePath);
我的问题是还有其他方法将图像写入数据库吗?每种方法的优点/缺点。 也许值得编写一个自定义流,将数据直接写入数据库?
注意:将图像存储到文件系统不是一个选项。
基准测试结果:
I need to generate and store a lot of small (1-10KB) PNG images (>10 millions) to the database.
The only thing I care is images/s throughput. For now I know two ways of storing GD image object to the database:
Use output buffer:
ob_start();
imagepng($image);
$imageData = ob_get_contents();
ob_end_clean();
Use temporary file (tmpfs/ramfs):
$tmpFilePath = '/dev/shm/file_000.png';
imagepng($image, $tmpFilePath);
$imageData = file_get_contents($thumbnail);
Update. There is a 3rd method: Use PHP memory stream:
// PHP streams are NOT supported
$tmpFilePath = 'php://memory';
imagepng($image, $tmpFilePath);
$imageData = file_get_contents($tmpFilePath);
My question is are there any other ways to write image to DB? Any pros/cons of each method.
Maybe it is worth to write a custom stream, which writes data to DB directly?
Note: Storing images to filesystem is NOT an option.
Benchmark results:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以尝试让
imagepng()
写入 内存流 而不是文件。虽然我不确定 imagepng() 函数是否可以处理 I/O 流,但如果可以的话,它可能是一个不错的选择。
You could try letting
imagepng()
writing to a memory stream instead of a file.Although I'm not sure the
imagepng()
function can handle I/O streams, if it does, it could be a nice alternative.我认为没有其他方法:
imagepng()
没有返回数据流的选项(在我看来是一个设计错误,但你要做什么)。上述哪种方式更适合你,你应该进行基准测试;编写流包装器可能是值得的,因为它节省了写入文件的步骤。
I don't think there is any other way:
imagepng()
doesn't have the option of returning the data stream (a design error in my eyes, but what are you going to do).Which of the abovementioned ways is better for you, you should benchmark; writing a stream wrapper might be worth it, because it saves the step of writing the file.
将图像写入临时文件只会增加磁盘 I/O,因此使用内存缓冲区是一个不错的选择。然后,您可以使用准备好的语句的 send_long_data 函数将它们上传到数据库中。 (但你可能已经知道了。)
Writing image to temporary file would only increase disk I/O, so using memory buffer is a good choice. You can then upload them into DB with prepared statement's send_long_data function. (But you probably already know that.)
两者都不太可能影响您的总运行时间,因为现在在 Linux 上 openreadclose 一个缓存文件大约需要 20 微秒。生成和压缩图像将非常耗时(您应该首先优化花费最多时间的部分)。如果您确实想节省 1% 的总时间,请使用 ob_() 函数。
无论如何,如果您想将它们存储在数据库中,请使用 BLOB 检查数据库连接库的性能,有些非常糟糕,有些则很快。
Both are unlikely to influence your total runtime since openreadclose'ing a cached file on linux these days takes about 20 microseconds. Generating and compressing the images is going to be the time-eater (you should optimize first the part that takes the most time). If you really want to save 1% on your total time, use the ob_() functions.
Anyway, if you want to store those in a database, examine your database connection library performance with BLOBs, some are pretty awful, others are fast.