存储大量图像

Sai*_*ine 49 filesystems tree image

我正在考虑开发自己的基于PHP的图库来存储大量图片,可能是成千上万.

在数据库中,我将指向图像的URL,但问题是:我知道让所有这些文件都位于服务器中的同一目录是不切实际的,因为它会减慢对爬网的访问速度,所以,你会怎么做?存储所有这些?某种基于jpeg/png名称的树?

你会推荐我对图像进行分区的规则是什么?

(它将专注于使用cheapo dot coms,因此不可能使用服务器进行修改)

Too*_*the 47

我们过去也遇到过类似的问题.并找到一个很好的解决方案

  • 为每个图像提供一个独特的指导.
  • 为每个图像创建一个数据库记录,其中包含子图像的名称,位置,guid和可能的位置(缩略图,缩小尺寸等).
  • 使用guid的第一个(一个或两个)字符来确定顶层文件夹.
  • 如果文件夹中有太多文件,请再次拆分.更新参考文献,您就可以开始了.
  • 如果文件数和访问次数过多,则可以将文件夹分布在不同的文件服务器上.

我们经历过使用guids,你会得到或多或少的统一分工.它就像一个魅力.

可能有助于生成唯一ID的链接:

  • @Gamecat恕我直言,比生成UUID更好的是简单地散列文件名并将其开头用作目录名.这样您就不需要数据库了,因为您总是可以重新计算哈希值,这比数据库访问要快得多.(我看到你提到了SHA-1,但没有明确建议). (7认同)
  • 因为性能,数据库调用通常非常昂贵,特别是对于像图像这样的二进制数据. (3认同)
  • 更不用说从数据库中提供图像意味着你几乎总是发送数据,就好像你可以从文件系统服务一样,你可以让浏览器/服务器处理图像的缓存 (3认同)
  • @maaartinus,你可能是对的.但是我们已经有了一个数据库(用于CMS),我们只需要与图片链接,这对我们来说非常有用. (2认同)
  • 如果您有一个整数唯一 ID,一个简单的方法是将它分成三个级别:xxx/yyy/filename.jpg。这样您就可以使用唯一 ID。例如,如果 id 为 100789,它将存储为 100/789/filename.jpg。那么每个级别最多有 1,000 个目录。并且共有 1,000,000 个文件。而且,您可以根据分辨率拥有多个文件名:thumbnail.jpg、small.jpg 等。 (2认同)

Cla*_*ton 11

几年前我在电子文档管理系统上工作,我们做了很多Gamecat和wic的建议.

也就是说,为每个图像分配唯一的ID,并使用它来导出图像文件的相对路径.我们使用类似于wic建议的MOD,但我们在每个级别允许1024个文件夹/文件,有3个级别,所以我们可以支持1G文件.

然而,我们从文件中删除了扩展名.DB记录包含MIME类型,因此不需要扩展名.

我不建议将完整的URL存储在DB记录中,只存储图像ID.如果存储URL,则无法在不转换数据库的情况下移动或重构存储.相对URL是可以的,因为您至少可以移动图像存储库,但如果您只存储ID并派生URL,您将获得更大的灵活性.

另外,我不建议允许从网络直接引用您的图像文件.而是向服务器端程序(例如,Java Servlet)提供URL,并在URL Query(http://url.com/GetImage?imageID=1234)中提供Image ID .

servlet可以使用该ID来查找数据库记录,确定MIME类型,派生实际位置,检查安全限制,记录等.


Mar*_*man 8

我通常只使用数值数据库id(auto_increment),然后使用modulu(%)运算符来确定放置文件的位置.简单且可扩展.例如,id为12345的图像路径可以像这样创建:

12345 % 100 = 45
12345 % 1000 = 345
Run Code Online (Sandbox Code Playgroud)

结束于:

/home/joe/images/345/45/12345.png
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

如果您使用的是Linux和ext3以及文件系统,则必须注意目录中可以包含的目录和文件数量有限制.dirs的限制是32000,所以你应该始终努力保持低数量的目标.

  • 同时拥有'345'和'45'的目的是什么?好像每个第一级目录(如'345')都只有一个子目录(在本例中为'45'). (12认同)

Adr*_*ith 7

我知道让所有这些服务器都位于服务器中的同一目录是不切实际的,因为它会减慢对爬网的访问速度.

这是一个假设.

我设计的系统中有数百万个文件存放在一个目录中,并且效果很好.它也是最容易编程的系统.大多数服务器文件系统都支持这一点而没有问题(尽管你必须检查你正在使用哪一个).

http://www.databasesandlife.com/flat-directories/

  • 感谢分享.OP提到PHP,一个实际问题是FTP访问具有大量文件的目录可能会超时. (2认同)
  • 我认为重要的是,正如您在博客文章中所做的那样,*某些*文件系统在单个文件夹中支持非常大量的文件.根据我的经验,一些(其他)文件系统在其规定的规范之外工作,用于大量文件,但并非所有文件操作都能正常工作.如果您要在单个文件夹中存储大量文件,请先测试它!也就是说,为什么不仅仅使用某种哈希来平衡文件夹结构呢? (2认同)

Isa*_*aac 5

保存与auto_increment id关联的文件时,我使用类似下面的内容,它创建三个目录级别,每个目录级别包含1000个目录,每个第三级目录中包含100个文件.这支持约1000亿个文件.

如果$ id = 99532455444,则以下返回/ 995/324/554/44

function getFileDirectory($id) {
    $level1 = ($id / 100000000) % 100000000;
    $level2 = (($id - $level1 * 100000000) / 100000) % 100000;
    $level3 = (($id - ($level1 * 100000000) - ($level2 * 100000)) / 100) % 1000;
    $file   = $id - (($level1 * 100000000) + ($level2 * 100000) + ($level3 * 100));

    return '/' . sprintf("%03d", $level1)
         . '/' . sprintf("%03d", $level2)
         . '/' . sprintf("%03d", $level3)
         . '/' . $file;
}
Run Code Online (Sandbox Code Playgroud)