存储不同大小的映像、文件系统或数据库方法


store multiple sizes of one image, filesystem or database approach

我知道这个问题已经被问过很多次了,但我更多的是关于存储多种尺寸的图像。

我已经决定将我的映像存储在文件系统中。所以,这是检查!

通过input type="file"上传的每个主图片将使用php中的unid函数获得一个唯一的id: uniqid('fc_', true)

现在,我的难题是如何存储主图像的不同大小(或子图像)。

现在,主映像在数据库中包含一条记录(id,标题,描述,类型,文件名),并存储在文件系统中。不同大小的主映像被直接移动到文件系统中(数据库中没有记录),它们使用主映像的惟一标识符+一些添加的文本进行命名。所以:

Master:  fc_345679849.89675849.jpg  
size (30px) : fc_345679849.89675849_tiny.jpg  
size (50px) : fc_345679849.89675849_small.jpg  
size (100px) : fc_345679849.89675849_medium.jpg  
size (500px) : fc_345679849.89675849_large.jpg

当我开始深入研究这个系统以及其他人是如何做的时候,我更加怀疑这是否是正确的方法。

我想到的另一种方法是存储每个图像(对图像的引用,而不是实际图像),包括数据库中不同大小的图像。它们都有一个主键,如果应用主键,则有一个对主图像的引用,如下所示:

id, ..., filename, master_imageid  
_____________________________
1, ... , 34.jpg, NULL  
2, ... , 23.jpg, 1  
3, ... , 45.jpg, 1  
4, ... , 12.jpg, 1  
5, ... , 8.jpg, 1

所以image 1是master,其余的(不同大小)是master的子元素…即图像2,3,4,5

所以,系统#1:一个记录的主,子没有db记录,并有一个方便的文本到各自的文件名链接到主。

系统#2:一个记录给主,一个记录给每个子。不需要在子文件的文件名中添加方便的文本,因为master_imageid列会自动链接到主文件。

有什么最好的解决方案吗?

Thanks in advance

我建议使用基于文件系统的方法。这样,您就可以使用简单的字符串操作获得各种大小的文件名;以数据库为中心的方法虽然很优雅,但增加了额外的间接层——假设没有数据库缓存,您将运行1个HDD读取来获得文件名+ 1个HDD读取来获得实际的图像数据,而不是运行1个ram内连接来获得文件名+ 1个HDD读取来获得实际的图像数据。这一点,再加上数据库往往引入的固有延迟,并没有描绘出美好的画面!

也就是说,使用数据库可能会提供一些优势。如果您不希望用户巧妙地在任何文件后面加上"_small"以获得更小的版本,那么毫无疑问,使用数据库可能是一种更有吸引力的方法。但即便如此,还是有更好的选择,特别是在没有缓存的情况下。

如果用户通过简单的URL操作访问文件确实是一个问题,我认为如果您将唯一的图像ID与分辨率说明符连接起来,并使用足够便宜但在小范围内防冲突的散列算法(想到MD5)对文件名进行散列来生成文件名,您可能仍然可以节省时间。

请注意,在任何程度的缓存加入战斗时,所有这些方法在性能方面都是微不足道的。理想情况下,如果不希望url可操作,则需要预先计算唯一文件名并将其存储在数据库中,并使用memcached/redis/whatever在运行时执行查找。

为什么要创建一个唯一的id,当每个数据库记录已经有一个唯一的id字段?

image table
id, created_by, etc

所以如果记录id是234,文件名将是234.jpg或其他。如果使用uniqueid()作为文件名,请确保检查文件名是否已经存在。如果在同一微秒内以某种方式创建了两个文件,则它们可以具有相同的唯一标识符。

也,什么是错误的附加文本为不同的大小?对我来说这是最好的办法。

234_thumb.jpg
234_small.jpg
234_large.jpg