成千上万的图片,我应该如何组织目录结构?(linux)

成千上万的图片,我应该如何组织目录结构?(linux),linux,directory-structure,Linux,Directory Structure,在我的Linux服务器上,成千上万的用户上传了数千张图片,该服务器由1和1.com托管(我相信他们使用的是CentOS,但不确定版本)。这是一个语言不可知的问题,但是,为了您的参考,我使用的是PHP 我的第一个想法是将它们全部转储到同一个目录中,然而,我记得不久前,一个目录中可以删除的文件或目录数量是有限制的 我的第二个想法是根据用户的电子邮件地址对目录中的文件进行分区(因为这正是我使用的用户名),但我不想遇到目录中目录的限制 无论如何,对于来自user@domain.com,我打算这样做: /

在我的Linux服务器上,成千上万的用户上传了数千张图片,该服务器由1和1.com托管(我相信他们使用的是CentOS,但不确定版本)。这是一个语言不可知的问题,但是,为了您的参考,我使用的是PHP

我的第一个想法是将它们全部转储到同一个目录中,然而,我记得不久前,一个目录中可以删除的文件或目录数量是有限制的

我的第二个想法是根据用户的电子邮件地址对目录中的文件进行分区(因为这正是我使用的用户名),但我不想遇到目录中目录的限制

无论如何,对于来自user@domain.com,我打算这样做:

/images/domain.com/user/images...
这样做明智吗?如果成千上万的用户说“gmail”,我甚至可以更深入,像这样

/images/domain.com/[first letter of user name]/user/images...
所以mike@gmail.com那将是

/images/domain.com/m/mike/images...
这是一个糟糕的方法吗?其他人在干什么?我不想遇到太多的目录问题也


相关的:


我用于另一个需求,但可以满足您的需要的是使用一个简单的约定

递增1并获取新数字的长度,然后以该数字作为前缀

例如:

假设“a”是使用最后一个id设置的变量

a = 564;
++a;
prefix = length(a);
id = prefix + a; // 3565
然后,您可以使用以下约定为目录使用时间戳:

20092305 (yyyymmdd)
然后你可以像这样分解你的路径:

2009/23/05/3565.jpg
(或以上)

这很有趣,因为您可以同时按日期和数字保持排序顺序(有时很有用)
您仍然可以在更多目录中分解路径

我将执行以下操作:

  • 在每个图像进入时对其进行MD5哈希
  • 在数据库中写入MD5散列,您可以在其中跟踪这些内容
  • 将它们存储在一个目录结构中,在该结构中使用MD5哈希十六进制字符串的前几个字节作为目录名。因此,如果散列为'abcdef1234567890',则将其存储为'a/b/abcdef1234567890'

  • 使用散列还可以合并多次上载的同一图像。

    要扩展Joe Beda的方法:

    • 数据库
    • 数据库
    • 数据库
    如果您关心按用户、原始文件名、上载日期、拍摄日期(EXIF)等对文件进行分组或查找,请将此元数据存储在数据库中,并使用适当的查询来选择适当的文件

    使用数据库主键(无论是文件散列还是自动递增的数字)在一组固定的目录中查找文件(或者,每个目录使用固定的最大文件数N,填充时转到下一个目录,例如,第k张照片应存储在
    {somepath}/aaaaaa/bbbbb.jpg
    其中aaaaaa=floor(k/N),格式为十进制或十六进制,bbbb=mod(k,N),格式为十进制或十六进制。如果层次结构太扁平,请使用类似于
    {somepath}/aa/bb/cc/dd/ee.jpg的内容


    不要直接向用户公开目录结构。如果用户使用web浏览器通过HTTP访问您的服务器,请为他们提供类似www.myserver.com/images/{primary key}的url并在内容类型标题中对适当的文件类型进行编码。

    这是我不久前为这种情况编写的两个函数。它们已经在一个拥有数千名成员的网站上使用了一年多,每个成员都有很多文件

    本质上,这个想法是使用每个成员唯一数据库ID的最后一位数字来计算目录结构,每个人都有一个唯一的目录。使用最后一位数字,而不是第一位数字,确保目录分布更均匀。每个成员的单独目录意味着维护任务要简单得多,而且您可以看到re的人的东西是(在视觉上)


    sanitize_var()是一个用于清除输入的支持函数,确保输入是数字的,$GLOBALS['site_path']是服务器的绝对路径。希望它们能不言自明。Joe Beda的答案几乎是完美的,但请注意,MD5在笔记本电脑上的iirc 2小时内被证明是可碰撞的

    也就是说,如果您真的以所描述的方式使用文件的MD5散列,您的服务将很容易受到攻击。攻击会是什么样子

  • 黑客不喜欢特定的照片
  • 他确保这是您正在使用的普通MD5(图像的MD5+秘密字符串可以吓跑他)
  • 他使用了一种神奇的方法,将一张(用你的想象)哈什的照片与他不喜欢的照片碰撞
  • 他像往常一样上传照片
  • 您的服务将用新服务覆盖旧服务,并同时显示两者
  • 有人说:我们不要覆盖它。然后,如果可以预测有人会上传一些东西(例如,网络上的一张流行图片可能会被上传),那么可以先把它放在“散列位置”。用户在上传小猫的图片时会很高兴,他会发现它实际上看起来像(在这里使用你的想象力).
    我说:使用SHA1,因为它在iirc 127年内被10000台计算机集群证明是可以破解的?

    在这个问题上可能已经晚了。但是有一个解决方案(如果它适合您的用例)可以是文件名哈希。这是一种使用文件名创建易于复制的文件路径的方法,同时还可以创建分布良好的目录结构。例如,您可以使用文件名哈希代码的字节作为路径:

    String fileName = "cat.gif";
    int hash = fileName.hashCode();
    int mask = 255;
    int firstDir = hash & mask;
    int secondDir = (hash >> 8) & mask;
    
    这将导致路径为:

    /172/029/cat.gif
    
    然后,您可以通过复制算法在目录结构中找到
    cat.gif

    使用十六进制作为目录名与转换
    int
    值一样简单:

    String path = new StringBuilder(File.separator)
            .append(String.format("%02x", firstDir))
            .append(File.separator)
            .append(String.format("%02x", secondDir)
            .toString();
    
    导致:

    /AC/1D/cat.gif
    
    几年前我写了一篇关于这一点的文章
    /AC/1D/cat.gif