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

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

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

比如:

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

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

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

新人求解,谢谢

阅读 15.7k
2 个回答

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

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

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就更短,对用户更友好。

传统的文件系统对目录层级和数量有限制, 现在主流的都用静态文件服务器, 又有那么多云存储, 即便是按路径存, 也是服务商给你虚拟出来的路径, 他的底层可能是另一种实现方式。 所以对于现在来讲, 静态文件目录层级的规划更多的意义是结构清晰。

我觉得按年/月/日/编号这么划分很合理呀,我用过。
我也用过打碎hash值的方式,就是hash值1-2位/hash值3-4位/hash值其余部分,你所说的可能就是这种方式。

只要是路径存到数据库,取出来又根据路径能访问到文件就好,没什么强制性,也没有明显的差别,按你自己心情存吧。上面的年月日可能要存完整路径, 而打碎hash只存hash就可以,程序取到hash后自己拼凑出文件路径。

至于没有扩展名, 这个就是文件被改名或者伪静态了。 如果是自己的服务器,可能配置了伪静态。如果用的是云存储, 就是在上传过程中改名了, 目标名和本地名不一致, 虽然剔除了扩展名, 但是一般云存储都允许你配置文件mime-type(或者自动),能让浏览器读的时候知道这是图片。

宣传栏