有人能指导我在网站上存储图片的最佳方式吗?我正在制作我的第一个MVC网站,并且想要创建一个带有对这些图像进行评论等功能的图像网站。
我使用JavaScript在画廊中显示我的图片,它需要图片的URL。我希望用户上传图片,但我不确定在服务器上存储图片的最佳方式是什么。我应该将它们保存在服务器上的文件夹中作为原始图片吗?或者最好使用SQL来处理数据,例如byte[]或文件流(Filestream),文件流能否给我所需的东西?还是有更好的方法吗?
谢谢
有人能指导我在网站上存储图片的最佳方式吗?我正在制作我的第一个MVC网站,并且想要创建一个带有对这些图像进行评论等功能的图像网站。
我使用JavaScript在画廊中显示我的图片,它需要图片的URL。我希望用户上传图片,但我不确定在服务器上存储图片的最佳方式是什么。我应该将它们保存在服务器上的文件夹中作为原始图片吗?或者最好使用SQL来处理数据,例如byte[]或文件流(Filestream),文件流能否给我所需的东西?还是有更好的方法吗?
谢谢
我建议将所有图片存储在一个名为images的文件夹中,然后在数据库中存储图片的路径。例如,如果我们正在发布文章并且每篇文章都有一张图片,我们可以将图片上传到/webroot/images/
并将路径/webroot/images/someimage.jpg
保存在数据库中。
如果网站要有大量的图片,最好进行进一步的组织,一个文件夹里有成千上万的文件不是很好,特别是如果你想要通过ftp连接,可以添加一个帖子id所在的文件夹(在我提到的例子中),这样它就会变成/webroot/images/[id]/image1.jpg
。
如果前缀始终相同/webroot/images
,则可以忽略其在数据库中的存储以节省一些磁盘空间,前提是应用知道图片文件夹的位置。另外,在第二个示例中,您可能会忽略id
,视图代码将如下所示:
<img src='<?= IMAGES_FOLDER."/".$post->getId()."/".$post->getImageName() ?>' />
当然,在文章中添加一个getImage()
函数是很好的,检查一下这个例子:
public function getImage()
{
return IMAGES_FOLDER."/".$this->getId()."/".$this->getImageName();
}
img
标签现在更加简洁。
<img src='<?= $post->getImage() ?>' />
PS: 在数据库中存储图像非常低效,因为数据库通常是应用程序的瓶颈,将图像存储在其中会增加数据库大小,并且每当访问网站上的任何图像时都会产生更多的请求,更不用说打开任何图像都需要运行一个 PHP (或其他所使用的语言) 脚本来提供该图像,这将增加服务器上的 RAM 使用量。
此外,由于您提到用户要上传图像,请尽量避免存储与上传的图像同名的图像,这样会让事情变得很傻,特别是对于长名称和使用空格等东西的名称,我通常通过对图像名称执行 md5
或生成随机字符串并进行 md5
来处理,以保持字符串长度恒定并且看起来更整洁,不要忘记双重检查图像是否存在以避免覆盖它。
当然,我提出的所有名称只是示例,您可以自由使用适合您的应用程序的名称。
虽然关于最佳存储图像位置的问题没有一种适用于所有情况的答案,但您可以选择将图像存储在外部文件存储服务(如Amazon S3、Azure等)中,并将图像的URL保存在数据库中,或者直接保存到数据库中(注意:如果您有大量图像,则永远不建议这样做)。然而,出于性能和安全相关问题的考虑,您应该考虑将图像放在Web服务器上。然而,正如我之前提到的那样,这取决于您的用例。在某些情况下,数据库甚至不是值得考虑的选项,您的服务器文件系统是最好的选择(通常在您没有太多BLOB且每个单位不超过1MB的情况下)。在其他情况下,通常需要一些(或更多)高级优化技术,数据库可能是更好的选择。往往情况下,这是在处理大量二进制数据(媒体、PDF等)的情况下。
对图像进行哈希处理,并将哈希值与记录一起存储,这样只要它们的哈希值相同,记录就可以共享同一张图像。
同时,将哈希值存储在二维嵌套文件夹中,这样就不会在同一个文件夹中得到太多文件。
例如,假设您有一张图像:sample.jpg。并且您对图像文件进行MD5哈希运算以获取哈希值:E4D2A7D3DE4A2B8C2DF。我会这样存储图像: ./DF/C2DF/E4D2A7D3DE4A2B8C2DF/sample.jpg
第一个目录是哈希值的最后两个字符,接下来的目录是哈希值的最后四个字符,最后一个目录则是完整的哈希值。这应该能够均匀地将图像分布在足够的文件夹中,避免了大多数文件系统可能出现的“一个文件夹中有太多文件”的问题。如果通过此方法仍然在一个文件夹中得到太多文件,您可以再次嵌套,将哈希值的最后六个字符作为另一个嵌套目录。