什么是在网站上上传和存储图片的最佳方式?

83

我不知道大型网站是如何在他们的服务器上保存图片的。有人可以告诉我他们如何把用户上传的图片保存到数据库中吗?

我想,也许他们只是将文件(图片)保存在某个路径下,然后在数据库中保存这个路径,对吗?

但我想以这种方式来做。这样做对吗?例如,一个名为www.photos.com的网站。当用户上传照片时,我会创建一个以用户名称命名的文件夹,并将这些照片保存在该文件夹中。

我相信我们可以使用php文件概念来创建目录。所以当新用户上传他的照片或文件时,我想创建一个以他的名字命名的目录。

例如:如果用户名为john,我将在photos.com上创建一个目录,形如www.photos.com/john/,然后在他上传照片时将所有照片保存到该目录中。这样做对吗?

这里没有人了解如何将文件保存到服务器上,所以请告诉我怎样做才正确且安全。


2
@AdrianCornish,你能告诉我你所说的“你尝试了什么”的意思吗?我不是让你为我编写代码,我只想知道大多数人遵循的算法或过程,这样如果我知道该做什么,我就可以继续前进。 - niko
你的问题表述不清 - 你问的是如何上传图片,而不是怎样将图片上传至你的网站并储存。此外,你有什么措施来防止用户上传恶意代码或带有隐藏式载荷的图片,以及阻止人们从可索引的 URL 上轻易地抓取所有的图片。 - Adrian Cornish
1
单词“database”有特殊含义。你误导了每一个试图回答你问题的人。但是,这是他们的错,因为他们实际上没有仔细阅读问题。 - Your Common Sense
@niko,我不明白为什么你接受了一个答案,显然它被你的第一行提问所误导,而且没有更新以回答你实际需要的内容... - Frankie
1
@Frankie,抱歉我不知道,但我接受了你的答案,感谢你让我知道这一点。我很感激你对答案的帮助。谢谢你,Frankie。 - niko
显示剩余2条评论
4个回答

248
所有大型网站不会将图片保存到数据库中,它们会将其存储在磁盘上。 它们会在表中保存图片位置的引用,并从那里进行链接。
为什么这样做呢?出于性能考虑。
从数据库中提取大量内容会成为性能瓶颈。而且数据库的水平扩展性并不好,所以这将带来更大的问题。所有大型网站都使用静态内容服务器来处理静态内容,比如图片。这些服务器对你的身份毫不关心。
那么,他们是如何确保图片真正私密的呢?实际上并没有。
图片的链接本身就是地址和密码。以Facebook为例,如果我在我的账户上存储了一张私密图片,你是不能打开它的。但只要你有正确的地址,就可以打开。 这张图片是私密的 注意文件名
10400121_87110566301_7482172_n.jpg
(由于Facebook不时更改URL,所以链接可能失效)

它是非连续的。获取图片的唯一方法是知道它的地址。
根据先前用户的照片,你无法猜测下一张照片。
它具有巨大的熵,所以即使你开始随机猜测,你会遇到大量失败,并且如果你确实找到一张照片,从那里你也无法识别出所有者的身份,这本身就是匿名保护。

编辑(为什么不应在“用户名”文件夹中存储图像):
在你的编辑之后,清楚地表明你打算将文件存储在磁盘上而不是数据库中。这个编辑涵盖了新的情况。

尽管你的逻辑(为每个用户创建一个文件夹)看起来更有组织性,但当你开始拥有许多用户和许多图片时,它会产生问题。想象一下你的服务器有1T的磁盘空间。我们假设1T与服务器的负载相当准确。

现在你有11个用户,假设他们同时开始上传,并且每个人都会上传超过100GB的文件。当他们每个人达到91GB时,服务器就已经满了,你必须开始将图片存储在另一台服务器上。如果按照这种用户/文件夹结构进行操作,你将不得不选择一个用户并将他的所有数据迁移到另一台服务器上。此外,这对于不能上传超过1T文件的用户来说也是一个硬性限制。 那我应该把所有文件都存储在同一个文件夹中吗?
不,大型网站通常会将文件存储在连续的文件夹中(/000001/,/000002/等),每个文件夹中有一个预定义数量的文件。这主要是为了解决文件系统性能问题。 2023年修订版,额外的检查
如今,大多数大公司在提供资源/图片之前也会检查用户是否被允许使用。但逻辑基本保持不变。除了上述描述之外,在提供资源之前,你还需要在数据库中进行双重检查以确定用户是否被允许。
更多关于一个目录中有太多文件怎么办?的信息。

23
精彩的解释。正是我所需要的,谢谢。 - CyberJunkie
2
谢谢你,Frankie。这确实非常清晰。但是还有另一种更有趣的方式:将图片存储在特定的图片存储提供商上。 - Fred
1
@Fred绝对正确。这个答案是专门为那些对事情如何运作毫无头绪的人设定的正确心态。一旦您开始在您的网站上托管数百万张图片,您可能会想要拆分问题和/或外包托管这些资产。然而,心态仍然保持不变。在数据库中,您只引用图像位置。感谢您的评论。 - Frankie
有没有一个处理这个问题的框架/工具/实现,我们可以直接使用或者至少了解如何自己做?(也就是说,要在数据库中存储哪些详细信息,如何对文件夹和文件进行编号等) - Daniel
1
@Daniel,我不知道是否有现成的库可以使用,但我可以确定的是,大多数“大型网站”,如果不是全部,都有定制的解决方案。关于给文件编号,你需要选择一种能够最小化冲突的方法。如果你按顺序编号,多个服务器可能会选择相同的“键”。你应该采用上述所描述的命名方式;即随机哈希值。 - Frankie

9
通常情况下,如果网站访问量较大,将图片存储在数据库中是一个不好的想法。传统上,数据库是大多数应用程序中的主要瓶颈之一。没有必要过度加载它。如果图像在文件系统中,许多HTTP服务器(例如nginx)可以最有效地为其提供服务。
俄罗斯最大的社交网络Vkontakte正是这样做的:将图像存储在文件系统中。
另一个大型社交网络实现了复杂的可扩展blob存储。但我认为它对公众不可用。
总结:不要将Blob存储在数据库中。

4

这样做是正确的

是的。
我建议使用id而不是name。
www.photos.com/albums/1234/对初学者来说是可以的。


3

管理图片最好的方法是先将图片物理上传到服务器,然后在数据库中记录文件位置和图片详细信息。随后,可以配置一个搜索表单以允许用户进行文本搜索、零件号搜索或其他查询。可以编写一个PHP脚本,根据表中找到的数据生成有效的HTML图像标签。

将图片上传到MySQL™ BLOB字段中是一个很糟糕的想法,如果图片比缩略图大得多,则此类图片数据通常会出现问题。如果图片很大,您可能需要逐个复制/粘贴一个SQL INSERT语句(进入phpMyAdmin)。如果图片很大,并且SQL INSERT语句被您的文本编辑器拆分成两行,则永远无法还原图像。


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