如果我有一个网站,用户可以根据需要上传尽可能多的图片(想想像photobucket一样),设置文件存储的最佳方法是什么(同样,所有上传都会获得一个独特的随机时间戳)?
site root
--username
----image1.jpg
----image2.jpg
----image3.jpg
--anotheruser
----image1.jpg
----image2.jpg
----image3.jpg
...
或
siteroot
--uploads
----image1.jpg
----image2.jpg
----image3.jpg
----image4.jpg
----image6.jpg
...
----image50000.jpg
我认为第一种方法更有条理。但我认为第二种方法是标准的(保持所有上传在同一个目录中),但我想知道如果在同一目录中有数千张图像检索图像时它会更慢
---编辑---
感谢迄今为止的出色答案。 此外,我将创建缩略图,所以我还必须在某处插入该目录... 或,创建一个命名约定,如thumb_whatever.jpg。
这么多不同的方法。 是的磁盘空间将是一个问题。但是现在我关心的是检索时间。当我必须将图像输出到浏览器时,如果该图像位于包含10,000个其他图像的目录中,我担心它会有多慢。
答案 0 :(得分:19)
目录中的文件数应该对读取文件数据所需的时间完全没有影响 - 但是在开始读取文件之前,它可能会大大影响查找文件所需的时间。
主要问题启动的确切断点将从文件系统类型到文件系统类型不等,但是,一般来说,如果您谈论的是几百个文件,则不需要担心它。如果你谈的是几千,那么值得思考,也许还要做一些基准测试,看看你的文件系统和硬件如何处理它。如果你在谈论成千上万的文件,那么你真的需要开始解决问题。 (我曾经有一个Linux / e2fs打印服务器,其中CUPS在完成打印后没有删除其作业控制文件,并且它在一个目录中获得了大约100,000个文件。只是获取目录列表花了半个多小时才开始显示任何文件名。)
然而,按用户名分隔它们可能不是最佳选择,因为您可能会有很多用户上传极少数图片,而且可能会有一些人上传数百或数千张图片,可能会在这些图片中产生访问时间问题用户的存储目录。在这种情况下,更大的问题是你可能最终(假设一个成功的网站)有成千上万的用户和大量的子目录与大量的文件一样糟糕,因为减慢了对你的访问速度的影响数据
由于你将要对它们设置时间戳,我可能会做的是根据时间戳的 last 三位数将它们放入子目录中。这将在1000个子目录中相对均匀地分布文件,并且应该使每个目录中的文件数量保持相当小。 (使用前三个数字会导致一个目录被填充,然后移动到下一个目录而不是均匀地分配它们。)如果你在每个子目录中仍然有太多文件(这可能意味着你正在处理几个百万上传的图像),你可以为前三个数字添加第二个级别,所以upload-1234567890.jpg将最终在/567/890/upload-1234567890.jpg。
答案 1 :(得分:5)
答案就是“也许”。文件检索可能没什么问题,但是如果你需要对文件夹进行任何维护,那么当进程尝试枚举目录列表时,这将是一个非常令人头痛的问题。
改善情况的是图像文件夹下的一些子目录(或两个级别,具体取决于您要存储的图像数量),因此您有这样的层次结构:
siteroot
-- uploads
---- a
---- b
---- c
:
---- z
...然后根据第一个字母存储文件(所有名称以'a'开头的图像都进入文件夹'a')。你可以把它作为一个两个或三个字母的后缀(aa,ab,ac,ad ...,ba,bb,bc ...,zx,zy,zz),并且可能还有一个层次结构,所以你拆分多个文件夹中的文件,取决于名称的前四个字符。
如果文件随后被分配了一个随机字母数字名称,那么这将确保文件均匀分布在所有文件夹中(给定足够大的样本大小)。
您可能需要考虑混合使用选项(1)和在层次结构上拆分图像,如上所述。这将确保如果单个用户确实上传了大量文件,那么您将受到保护。同样,如果您正在查看许多用户目录,则同样的原则适用于确保您在单个父项下没有1,000,000个用户目录。
答案 2 :(得分:2)
尝试使用mongodb ...它是一个keyvalue db,它也允许存储二进制数据。它非常快速有效,支持分片(在多台机器上放置数据)开箱即用
你真的不想让文件夹和文件夹充满文件。管理这些文件夹需要永远,并且稍后更改命名/分割方案是一场噩梦。此外,如果磁盘空间不足,则会出现问题。另外,对于负载平衡,将一个硬盘装满文件效率不高
答案 3 :(得分:2)
我经常使用这样的架构: 上传/(#标识%1000)/img_#id.jpg
其中#id是ofc。存储在数据库中的照片的ID号(整数)。这提供了一个仅基于照片ID的简单模式。
答案 4 :(得分:1)
这取决于文件系统。例如,如果目录中有超过512个文件,则FAT16往往会非常慢。 FAT32和NTFS没有相同的限制,但如果你有大量的文件,运行速度要慢得多。即使您正在运行一个更强大的Linux文件系统,如果它们更小,您仍然可以更快地解析目录。
我肯定会选择#2 - 用户将图像分割成目录。
答案 5 :(得分:0)
我认为uploads目录下的子目录是最好的。
site root
--uploads
----username
------image1.jpg
------image2.jpg
------image3.jpg
----anotheruser
------image1.jpg
------image2.jpg
------image3.jpg
...
根据主机操作系统的不同,在一个目录中包含太多文件可能会导致一些令人头疼的问题。此外,根据您获取图像列表的方式,可能会导致性能问题。
另外,选项2会很乱。 :)