在网站中存储用户上传的图片:选择将图片存储在数据库还是文件系统?

8
我正在建设一个网站,用户可以上传图片。每个用户使用的最大空间也受到限制。
我有两个想法:
1. 使用类似于mongoDB的NoSQL数据库GridFS来存储图像。 2. 将图像存储在文件系统中,并在数据库中存储路径。
上述哪种方法更好?为什么呢?

2
这是非常主观的,但就个人而言,我总是会将图像放在文件系统中,这样它们可以被单独管理、访问、修改、分发和备份,而不是放在一个巨大的、无定形的多 TB 数据库中,需要花费数小时进行备份,甚至需要一堆 SQL 才能完成最简单的事情。你的情况可能有所不同。 - Mark Setchell
如果您将问题变得更加客观,那么这个问题可能更适合于programmers.stackexchange.com。两种方法都可以很好地解决问题,具体取决于多个因素(例如数据大小、使用模式、服务器数量等)。请尝试编辑此问题,使其更加具体和可回答。 - Christian P
你应该考虑托管和管理大型MongoDB解决方案与文件系统或AWS S3 / Azure Blob /等解决方案的成本。 - WiredPrairie
1个回答

14

,为什么每个人都跳到GridFS呢?

根据图像的大小和确切的用例,我建议将图像直接存储在数据库中(而不是通过GridFS)。这是原因:

文件系统

  • 将图像存储在文件系统中被证明效果良好,但这并不是易事
  • 您需要不同的备份系统、故障转移、复制等,这在 DevOps 方面可能会很棘手
  • 您需要创建一个智能目录结构,这是一个有漏洞的抽象,因为不同的文件系统具有非常不同的特性。一些文件系统在一个文件夹中存储 16k 个文件没有问题,而另一些则在仅有 1k 个文件时就开始 choke。一种常见的方法是使用惯例,比如 af/2c/af2c2ab3852df91.jpg,其中文件夹 af2c 是从文件名推断出来的(文件名本身可能是内容的哈希值,用于去重)。

GridFS

GridFS 专门用于存储大型文件,并以类似于文件系统的方式存储文件。这带来了一些缺点:

  • 对于每个文件,您需要一个fs.file和一个fs.chunk文档。对于大型文件,chunking 是绝对必需的,但如果您的文件平均值低于 256k,则实际上没有真正的 chunking(默认 chunk 大小为 256k)。因此,在 GridFS 中存储小文件时,您会得到开销而没有好处。这也需要两个查询而不是一个。
  • 它对您的集合强加了一定的结构,例如要有“文件名”。这取决于用例,但我经常选择使用散列作为ID,并将散列存储在用户中,例如。它去重、易于实现、与缓存完美对齐并且不需要想出任何惯例。由于索引是字节数组,它还非常高效。

如果您在为摄影师运营一个网站,他们可以上传10MB的RAW文件或大型JPEG文件,则情况可能会有所不同。在这种情况下,GridFS可能是一个不错的选择。对于存储用户图像、缩略图等,我会简单地将图像放在自己的文档中。


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