我不知道是否可以对这种决定进行一般性观察,因为这实际上取决于您要做什么以及优先级列表 NFR(例如性能和响应时间)对您的应用程序的影响。
如果您有很多用户,上传大量二进制文件,并且系统为大量上传的二进制文件提供服务,那么您会遇到在数据库中存储文件的成本包括:
好处是
- 原子提交
- 扩展随数据库一起提供(尽管使用 MySQL,但使用多节点等存在一些问题)
- 管理文件系统等的繁琐和复杂的代码
鉴于您存储到文件系统的相同用户情况,您需要解决
- 缩放
- 文件名管理(用户上传同名文件两次等)
- 在数据库中创建相应的记录以映射到磁盘上的文件(以及围绕所有这些的代码)
- 照顾您的 apache 配置,以便它们从文件系统提供服务
对于我们的 Grails 站点,我们有一个类似的问题需要解决,其中内容编辑器每天要上传数百张图片。我们知道,当应用程序可以更好地用于其他处理时,通过应用程序驱动所有需求是浪费的(考虑到对页面的预期需求将达到每周数百万,我们绝对不希望图像削弱我们)。
我们最终创建了上传 -> 文件系统解决方案。对于每个上传的文件,都会创建一个 DB 元数据记录并与上传过程一起管理(相反,在生成图像的 GSP 内容链接时读取该记录)。我们根据浏览器请求的链接直接通过 Apache 提供磁盘请求。但是,总是有一个但是,请记住,对于文件系统之类的东西,每台机器只有内容。
我们为确保图像重新同步到每台服务器上而感到头疼,因为与位于集群后面并支持集群行为一致的数据库不同,文件绑定到服务器上的物理位置。
文件系统可能遇到的另一个问题是文件夹内容大小。当您开始拥有包含数以万计文件的文件夹时,操作系统级别的文件夹扫描开始真正拖累。为了避免这个问题,我们必须编写代码来管理图像上传到 yyyy/MM/dd/image.name.jpg 文件夹结构中,这样没有一个文件夹会累积数十万张图像。
我的意思是,虽然我们通过不将数据库用于 BLOB 存储而获得了我们想要的性能,但这是以开发开销和系统管理为代价的。