在Web服务器上存储用户上传的文件

7

我正在制作一个允许用户上传文件(图片和其他类型)的网站。我在这个领域没有任何经验,希望得到一些有关正确存储和索引这些文件的意见。

虽然我希望拥有一个良好的架构来承载大量数据,但目前我并不担心像Facebook、Google那样的极高数据量。

我考虑将文件存储在文件系统中的

/files/{username}/

然后拥有一个名为uploads的数据库,每个用户都有自己的表格,其中包含他上传的每个文件(因此也包含URL),以及我想要存储的任何其他额外信息。 然而,将每个用户分配一个独立的表格似乎非常低效,而在单个表格中维护所有文件的记录也不正确,因为每次访问单个文件时都需要搜索整个表格。 我考虑给每个用户分配自己的表格是因为这是一种整洁而独特的方式来将数据分片到表格中,并减少查找时间,以便找到给定用户的文件。
2个回答

4
如果你想实现按用户级别访问图片,那么Matt H提出的建议是一个好主意。但鉴于你在数据库存储空间上受限,将图像存储为二进制数据是低效的,正如你所说。
每个用户使用一个表格是不好的设计。上传文件的用户应该只是存储所有文件上传的表格中的一个字段/列,以及任何文件元数据。我建议为文件名生成GUID,这保证了其唯一性,并且比自增字段更好,因为后者很容易被猜测,如果你试图防止用户访问所有图片。
你关心性能,但在处理数百万条记录之前,选择属于特定用户、在特定时间范围内上传的图片的查询成本微不足道(假设你正在存储时间戳或类似信息)。如果速度是一个问题,你可以在用户名上添加B树索引,这将显著加快用户特定图片查询的速度。
回到安全、访问和组织的话题。为每个用户存储一个文件夹来存储图像(尽管根据用户数量,文件夹数量可能会增长到无法管理的水平)。如果您不希望图像公开可用,请将它们存储在非 Web 文件夹中,使您的应用程序读取数据并流式传输以呈现用户的图像。这更加复杂,但可以隐藏实际的文件免受互联网攻击。此外,您将能够通过经过身份验证的用户验证所有请求的图像。

3
这取决于您的应用程序和数据库的性质和结构。我使用过许多技术,包括基于文件夹的技术、存储在数据库blob中的图片、通过身份验证网关访问的离线文件夹等等。
对于与应用程序或数据库无直接关联的外部图片(如临时照片等),我倾向于将其放在一个文件夹中。由于您的结构似乎是用户上传的图片,那么我预计可能会有与图片相关的元数据,例如标签。在这种情况下,我可能会将图片存储在数据库表中,假设我有这样的容量。如果需要保护照片,使其他未经认证的用户无法访问,则数据库将具有自己的安全性,而基于文件的存储则需要某种技巧来防止未经授权的访问。
我不会为每个用户使用一个表,只会使用一个图片表,其中包含ID、用户ID和图片blob元素。
这有帮助吗?

它确实有帮助。但是,还存在一些问题。目前,我们正在使用共享的Web服务器,每个数据库限制为1GB,因此将图片/文件作为blob存储在数据库本身中将不可行。此外,将所有图片放在一个表中是否会增加特定图片的搜索时间?我之所以按用户分表,是因为知道用户后,我就知道要搜索哪个表,从而只需搜索较少的记录(可以将其视为基于userid的分片)。这不合理吗?我有什么遗漏的吗? - Ayush
1
索引的大小会影响SQL执行,但是一大堆未索引的BLOB不会被注意到。但如果你没有空间,这就是一个无意义的问题。在这种情况下,您需要将它们存储在文件系统中。如果您有很多用户ID/照片文件夹结构是可以的,因为避免单个文件夹中的大量文件计数是一个好的实践。我会放置一个.htaccess来避免直接访问(假设您需要授权才能访问它们),并使用一个photo?id=whatever,将头文件更改为image/jpeg或其他格式,并回显readfile的图像。 - Matt H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接