网站存储图片的最佳方法

11

有人能指导我在网站上存储图片的最佳方式吗?我正在制作我的第一个MVC网站,并且想要创建一个带有对这些图像进行评论等功能的图像网站。

我使用JavaScript在画廊中显示我的图片,它需要图片的URL。我希望用户上传图片,但我不确定在服务器上存储图片的最佳方式是什么。我应该将它们保存在服务器上的文件夹中作为原始图片吗?或者最好使用SQL来处理数据,例如byte[]或文件流(Filestream),文件流能否给我所需的东西?还是有更好的方法吗?

谢谢


1
如果我不在工作的话,我会给你一个详细的答案,但是在我的公司MVC(CodeIgniter的修改版本)中,我将图片存储在mySQL的longblob字段中(基本上是存储原始图像数据),并通过php脚本显示这些图片。例如,如果我想从数据库中检索id为1的图像,我会访问/image/1,然后它会显示该图像。将这些数据存储在数据库中的好处是我可以对其进行操作和缓存,这对于像你们这样的图片网站来说是很有用的。我们的系统还支持/image/1/resize/100/100,并且会自动进行缓存以提高速度。 - SixteenStudio
3个回答

14

我建议将所有图片存储在一个名为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 来处理,以保持字符串长度恒定并且看起来更整洁,不要忘记双重检查图像是否存在以避免覆盖它。

当然,我提出的所有名称只是示例,您可以自由使用适合您的应用程序的名称。


1
感谢您的帮助。我还有一个问题要问别人,我想在某个时候也做视频,所以我需要一个带有大型文件存储的asp.net mvc4主机。有人知道一个好的便宜网站吗? - Mike Loder
询问便宜的服务有点跑题,但如果您需要非常大的存储空间,我建议您看看亚马逊S3服务。 - Mohammad AbuShady

0

虽然关于最佳存储图像位置的问题没有一种适用于所有情况的答案,但您可以选择将图像存储在外部文件存储服务(如Amazon S3、Azure等)中,并将图像的URL保存在数据库中,或者直接保存到数据库中(注意:如果您有大量图像,则永远不建议这样做)。然而,出于性能和安全相关问题的考虑,您应该考虑将图像放在Web服务器上。然而,正如我之前提到的那样,这取决于您的用例。在某些情况下,数据库甚至不是值得考虑的选项,您的服务器文件系统是最好的选择(通常在您没有太多BLOB且每个单位不超过1MB的情况下)。在其他情况下,通常需要一些(或更多)高级优化技术,数据库可能是更好的选择。往往情况下,这是在处理大量二进制数据(媒体、PDF等)的情况下。


1
一个很好的存储二进制数据的服务是Microsoft Azure。虽然一开始可能需要学习很多,但它非常易于使用。以下是一个简单的步骤指南,介绍如何在简单应用程序中集成:https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-nodejs - Temy

0

对图像进行哈希处理,并将哈希值与记录一起存储,这样只要它们的哈希值相同,记录就可以共享同一张图像。

同时,将哈希值存储在二维嵌套文件夹中,这样就不会在同一个文件夹中得到太多文件。

例如,假设您有一张图像:sample.jpg。并且您对图像文件进行MD5哈希运算以获取哈希值:E4D2A7D3DE4A2B8C2DF。我会这样存储图像: ./DF/C2DF/E4D2A7D3DE4A2B8C2DF/sample.jpg

第一个目录是哈希值的最后两个字符,接下来的目录是哈希值的最后四个字符,最后一个目录则是完整的哈希值。这应该能够均匀地将图像分布在足够的文件夹中,避免了大多数文件系统可能出现的“一个文件夹中有太多文件”的问题。如果通过此方法仍然在一个文件夹中得到太多文件,您可以再次嵌套,将哈希值的最后六个字符作为另一个嵌套目录。


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