方案
用户可以发布项目并在帖子中包含最多5个图像,上传的每个图像都需要重新采样和调整大小 - 总共创建4个额外图像。这意味着,如果用户上传了5张图像,最终会有25张图像存储起来。
假设
可能的方法
任何人都有关于存储图像的最佳实践/方法的经验吗?
注意:我预先有人会提到S3 - 让我们假设我们想暂时保留本地图像。
感谢您寻找
答案 0 :(得分:12)
我们有大量生产这样的系统,迄今为止有30,000多个文件和20多GB ......
Column | Type | Modifiers
-------------+-----------------------------+----------------------------------------------------------
File_ID | integer | not null default nextval('"ACRM"."File_pseq"'::regclass)
CreateDate | timestamp(6) with time zone | not null default now()
FileName | character varying(255) | not null default NULL::character varying
ContentType | character varying(128) | not null default NULL::character varying
Size | integer | not null
Hash | character varying(40) | not null
Indexes:
"File_pkey" PRIMARY KEY, btree ("File_ID")
文件只存储在一个目录中,整数File_ID作为文件名。我们超过30,000没有问题。我测试得更高没有问题。
这是使用RHEL 5 x86_64和ext3作为文件系统。
我会这样做吗?不,请允许我分享一些关于重新设计的想法。
数据库仍然是文件信息的“主要来源”。
每个文件都是sha1()散列并存储在基于该散列的文件系统层次结构中:
/FileData/ab/cd/abcd4548293827394723984723432987.jpg
数据库在每个文件上存储元信息方面要聪明一些。这将是一个三表系统:
File
:存储名称,日期,IP,所有者和指向Blob(sha1)的指针等信息
File_Meta
:在文件上存储键/值对,具体取决于文件类型。这可能包括Image_Width等信息。
Blob
:存储对sha1的引用及其大小。
该系统通过存储散列引用的数据来重复删除文件内容(多个文件可以引用相同的文件数据)。使用rsync备份同步文件数据库非常容易。
此外,将删除包含大量文件的给定目录的限制。
文件扩展名将存储为唯一文件哈希的一部分。例如,如果空文件的哈希是abcd8765
...空.txt
文件和空.php
文件将引用相同的哈希。相反,他们应该引用abcd8765.php
和abcd8765.txt
。为什么呢?
Apache等可以配置为根据文件扩展名自动选择内容类型和缓存规则。使用有效名称和反映文件内容的扩展名存储文件非常重要。
你知道,这个系统可以通过委托通过nginx传递文件来提高性能。见http://wiki.nginx.org/XSendfile。
我希望这在某种程度上有所帮助。小心。
答案 1 :(得分:1)
我会将所有图像存储在一个文件夹中 - 然后数据库会跟踪文件名 - 保持简单
答案 2 :(得分:0)
首先,我建议为图像创建一个表。这是一行/图像文件表:
| id | filename | type | storage |
---------------------------------------
| 123 | 123.png | original | store1 |
id
auto incremental int或同样独特的东西。filename
文件base name。这允许您移动文件并只更新代码。文件名可以是{file_id}.{extension}
。type
是图片的类型:original
,thumbnail
,resized
,等等。也可以是尺寸:100x100
,500x
,x500
(其中500x
将是无限高度,x500
将是无限宽度)。这只是一些例子。storage
将是文件所在的标识符,这可以是目录。假设您将图像存储在post_images
中,文件名为123.png
,存储空间为store1
,则路径为post_images/store1/123.png
。我自己还没试过,但我在同一目录中存储10k +文件的网络应用程序存在问题。