存储大量的图像

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

在数据库中,我会指向图像的URL,但是这里有个问题:我知道把它们全部放在服务器的同一个目录下是不切实际的,因为它会减缓对爬虫的访问,所以,你会如何存储所有这些? 某种基于jpeg / png名称的树?

什么规则来分割图像,你会推荐我?

(它将专注于使用廉价的点com,所以不可能与服务器混淆)

我们过去也有类似的问题。 并find一个不错的解决scheme

  • 给每个图像一个独特的指导。
  • 为每个图像创build一个数据库logging,其中包含名称,位置,guid和子图像的可能位置(缩略图,缩小尺寸等)。
  • 使用guid的第一个(一个或两个)字符来确定顶层文件夹。
  • 如果文件夹文件太多,请重新分割。 更新参考,你准备好了。
  • 如果文件数量和访问量太高,则可以将文件夹分散在不同的文件服务器上。

我们已经体会到,使用GUID,你会得到或多或less统一的分工。 它的function就像一个魅力。

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

几年前,我曾经在电子文档pipe理系统上工作过,而且我们做了很多Gamecat和wic的build议。

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

然而,我们从文件中删除了扩展名。 DBlogging包含MIMEtypes,所以不需要扩展名。

我不build议将完整的URL存储在数据库logging中,只有图像ID。 如果您存储了URL,则无需移动或重新构build存储,而无需转换数据库。 一个相对的URL是可以的,因为这样你至less可以移动图像库,但是如果你只是存储这个ID并获得URL的话,你将会获得更大的灵活性。

另外,我不build议直接引用来自networking的图像文件。 相反,提供一个URL到服务器端程序(例如Java Servlet),图像ID在URL查询( http://url.com/GetImage?imageID=1234 )中提供。

servlet可以使用该ID来查找数据库logging,确定MIMEtypes,派生实际位置,检查安全限制,logging等。

我通常只使用数字数据库id(auto_increment),然后使用modulu(%)运算符来确定放置文件的位置。 简单和可扩展。 例如,图像ID为12345的path可以像这样创build:

 12345 % 100 = 45 12345 % 1000 = 345 

结束于:

 /home/joehttp://img.dovov.com345/45/12345.png 

或类似的东西。

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

我知道让所有人都坐在服务器的同一目录下是不切实际的,因为这会降低对爬网的访问速度。

这是一个假设。

我devise了一个系统,我们把数百万个文件存放在一个目录中,而且效果很好。 这也是最简单的编程系统。 大多数服务器文件系统支持这个没有问题(虽然你必须检查你正在使用哪一个)。

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

当保存与auto_increment id相关联的文件时,我使用如下所示的内容,它创build了三个目录级别,每个目录级别由1000个dirs和每个第三级目录中的100个文件组成。 这支持大约100亿个文件。

如果$ 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; } 

看看XFS文件系统。 它支持无限数量的文件,Linux支持它。 http://oss.sgi.com/projects/xfs/papers/xfs_usenix/index.html

你可能alawys在表中有一个DateTime列,然后将它们存储在以月份,年份,甚至是月份,date,年份命名的文件夹中添加到表格中的图像。

  1. 2009年
  2. -01
  3. –01
  4. –02
  5. –03
  6. –31

这样你最终没有更深的3个文件夹。

我目前正面临着这个问题,而艾萨克写的东西让我对这个想法感兴趣。 我的function有点不同。

 function _getFilePath($id) { $id = sprintf("%06d", $id); $level = array(); for($lvl = 3; $lvl >= 1; $lvl--) $level[$lvl] = substr($id, (($lvl*2)-2), 2); return implode('/', array_reverse($level)).'.jpg'; } 

我的图片只有成千上万,所以我只有999999的限制,所以它会分成99/99 / 99.jpg或43524分成04/35 / 24.jpg

使用文件系统的层次结构。 使用像001/002/003 / 004.jpg这样的ID来标识你的图像会非常有帮助。 分区是一个不同的故事,但。 可以是随机的,基于内容的,基于创builddate等。真的取决于你的应用程序是什么。

您可以查看Apple iPod用于存储多媒体内容的策略。 有一个深度级别的文件夹和标题宽度相同的文件。 我相信,苹果公司的人们花费了大量的时间来testing他们的解决scheme,这样可能给您带来一些即时的好处。

如果您正在处理的照片是数码照片,则可以使用EXIF数据对它们进行sorting,例如通过拍摄date进行sorting。

您可以将图像作为blob( varbinary for mssql)存储在数据库中。 这样你就不必担心存储或目录结构。 唯一的缺点是你不能轻松地浏览这些文件,但是在一个平衡的目录树中很难。