请问图片存储的路径规则什么样最好?


我以前一直用 年/月/日 这样的规则来根据图片日期来对图片进行存储

我发现还有一些网站的存储路径比较奇怪,看不出有什么规则一样,但是很多网站都是这样

比如:

http://www.xxxx.com/d/ f3 / f5 /1191622119e32f5f3dl.jpg

http://www.xxxx.com/b/ 2c / b3 /1168060095865b32cbl.jpg

http://www.xxxx.com/icon/ 716 / 167716 /282dfc09b14691c1176caf2c1ffcf93e_50

上面这三个地址的存储是用的什么规则比日期存储更好?求解

还有就是后面这个地址它没有后缀名是怎么实现的我知道那个_后面应该是缩略图尺寸

新人求解,谢谢

编程 图片存储 文件存储

夜.寒蝉鸣泣时 10 years, 6 months ago

我以前一直用 年/月/日 这样的规则来根据图片日期来对图片进行存储

这个方案不错。可能有一个问题就是图片很多的情况下,可能会出现图片重复上传的情况,浪费空间。

f3/f5/1191622119e32f5f3dl.jpg

这类都是对图片做hash,这样同样的图片会有一样的文件名,不会重复。

之所以要分目录,是因为一个目录里面太多文件会有性能问题(而且单个目录下文件数目是有限制的,这个取决于文件系统)

至于具体的做法,一个最简单的做法就是一个hash前2位作为一级目录名,3、4位作为二级目录名,剩下的位数作为文件名。

这个做法有一个问题,就是如果你获取一个文件,单独从文件名无法知道这个文件的hash,还要知道目录名才行,这样不太方便。所以更好的做法是直接用hash值作文件名,然后取前几位作目录名。

这里还有一个小问题,就是如果你以后打算换hash算法,可能换算法之后,会有一个极小的概率,就是不同的图片,因为hash算法不同,hash值一样,这种情况下,文件名和目录名都会一样。万一你碰到了,那么旧文件就会无声无息地被覆盖!当然,你代码里可以作检查,不会覆盖同名文件,但是这种情况下,这个新文件仍然存在没地方放的问题。

所以一个改良的方案是直接用hash做文件名,然后对hash算法+文件名再作hash,这样得出目录名。对文件名再作hash,可以使用同样的hash算法,也可以使用不一样的(因为对文件作hash,为了防止碰撞,可能要用安全一点的hash算法,但是对文件名作hash,因为只是为了得出目录名,就可以用不那么安全但是性能更好的hash算法)。

例如,假设我们对一张图片作SHA256之后的结果是


 80fb7a9df5c1cd28fb815f22de3bad90dcd38703e72c6c5651dba9a5025c1f73

然后我们再对下面的字符串作md5:


 SHA256 80fb7a9df5c1cd28fb815f22de3bad90dcd38703e72c6c5651dba9a5025c1f73

对这个字符串作md5,结果如下:


 1ca5b331951f07ff9d5cd8ba3d541b5d

于是最后的url就是


 /1ca/5b3/80fb7a9df5c1cd28fb815f22de3bad90dcd38703e72c6c5651dba9a5025c1f73

这里每个目录采用了3位,这是非常海量图片的情况,一般而言每个目录2位也就够了。

当然,实际应用中,你如果确定不会换hash算法——通常也没必要换——那就没必要这么弄了。

如果图片不多的话,你也不一定要用“安全的”算法,因为它们通常性能相对较差,而且会使得url很长。 md5就可以了。

还有就是后面这个地址它没有后缀名是怎么实现的

这个有很多种可能:

  • 可以是服务器设置rewrite,就是 /image/a 的时候,自动转到 /image/a.jpg
  • 也可以是应用里面设置路由。
  • 还可能就是这个应用不依赖文件名后缀来判断文件类型(只要读取一个文件的前面一些字符,就能够很容易地判断出文件类型)。

上面提到的都是如何存储,实际上,因为可以配置rewrite规则,所以实际的url可以不一样。例如,hash值是16进制的,也就是说只有 [0-9a-f] ,可以再做base62变换,这样显示的url就更短,对用户更友好。

卖女孩的小柴火 answered 10 years, 6 months ago

Your Answer