Rails:在数据库中存储二进制文件

时间:2009-04-09 17:25:19

标签: ruby-on-rails

使用Rails,我有理由在文件系统而不是数据库中存储附件(可能是任何时间的文件)吗?数据库对我来说似乎更简单,无需担心文件系统路径,结构等,只需查看blob字段即可。但是大多数人似乎都在使用文件系统,它让我觉得这样做有一些好处,我没有得到,或者使用数据库进行这种存储会有一些缺点。 (在这种情况下,我正在使用postgres)。

6 个答案:

答案 0 :(得分:28)

这是一个非常标准的设计问题,并没有真正的“一个真正的答案”。

我通常遵循的经验法则是“数据进入数据库,文件进入文件”。

要记住的一些注意事项:

  1. 如果文件存储在数据库中,您将如何通过http提供服务?请记住,您需要设置内容类型,文件名等。如果它是文件系统上的文件,Web服务器会为您处理所有这些内容。非常快速有效(甚至可能在内核空间中),不需要解释代码。

  2. 文件通常很大。大数据库当然是可行的,但它们很慢并且不便于备份等。为什么在不需要的时候使数据库变得庞大?

  3. 很像2.,将文件复制到多台机器非常容易。假设您正在运行群集,您可以定期将文件系统从主计算机rsync到您的从属服务器并使用标准的静态http服务。显然,数据库也可以聚类,它不一定是直观的。

  4. 另一方面,如果您已经在集群数据库,那么必须处理集群文件是管理复杂性。这就是考虑在DB中存储文件的原因,我想说。

  5. 数据库中的Blob数据通常是不透明的。您不能过滤它,按它排序或按它分组。这减少了将其存储在数据库中的价值。

  6. 另一方面,数据库理解并发性。您可以使用标准的事务隔离模型来确保两个客户端不会同时尝试编辑同一个文件。这可能很好。不是说你不能使用锁定文件,但现在你有两件事需要理解,而不是一件。

  7. 辅助功能。可以使用常规工具打开文件系统中的文件。 Vi,Photoshop,Word,无论你需要什么。这很方便。你打算怎么用blob字段打开那个word文档?

  8. 权限。文件系统具有权限,它们可能是后方的痛苦。相反,它们可能对您的应用程序有用。如果您正在利用7,权限将真正咬你,因为几乎可以保证您的Web服务器以不同于您的应用程序的权限运行。

  9. 缓存(来自下面的sarah mei)。这会在客户端播放上面的http问题(你会记得正确设置生命周期吗?)。在服务器端,文件系统上的文件是一种非常容易理解和优化的访问模式。您的数据库可能会或可能不会很好地优化大型blob字段,并且您几乎可以保证从数据库到Web服务器还有额外的网络访问。

  10. 简而言之,人们倾向于使用文件系统来处理文件,因为它们最好地支持类似文件的习语。没有理由你必须这样做,文件系统变得越来越像数据库,所以最终看到完全收敛并不会让我感到惊讶。

答案 1 :(得分:6)

关于将文件系统用于文件有一些很好的建议,但这里还有别的想法。如果您要存储敏感或安全的文件/附件,使用数据库确实是唯一的方法。我已经构建了无法将数据放在文件中的应用程序。出于安全原因,必须将其放入DB中。您不能将它留在文件系统中,以便服务器/机器上的用户在没有适当安全的情况下查看或使用它们。使用像Oracle这样的高级数据库,您可以非常紧密地锁定数据,并确保只有适当的用户才能访问这些数据。

但其他要点非常有效。如果您只是执行诸如头像图像或非敏感信息之类的操作,那么对于大多数插件系统来说,文件系统通常更快,更方便。

数据库很容易设置为发回文件;这是一个更多的工作,但如果你知道你在做什么只需几分钟。所以,是的,文件系统是更好的整体方式,IMO,但当安全或敏感数据是一个主要问题时,数据库是唯一可行的选择。

答案 2 :(得分:2)

Erik的回答很棒。我还要补充一点,如果你想进行任何缓存,缓存静态文件要比缓存数据库内容容易得多,也更简单。

答案 3 :(得分:2)

我不知道blobstores有什么问题。您始终可以从中重建文件系统存储,例如通过在使用系统时将内容缓存到本地Web服务器。 但是权威商店应该始终是数据库。这意味着您可以通过折腾数据库并从源代码管理中导出代码来部署应用程序。完成。 添加Web服务器完全没有问题。

答案 4 :(得分:0)

如果您使用Paperclip等插件,则无需担心任何问题。有一个叫做文件系统的东西,这是文件应该去的地方。仅仅因为它有点难,并不意味着你应该把你的文件放在错误的地方。使用回形针(或其他类似的插件)并不难。那么,gogo文件系统!

答案 5 :(得分:0)

无法找到该问题的最新答案,因此我已经实现了 自Rails 5.2起提供了用于Active Storage的数据库服务,该服务与任何其他Active Storage服务一样,但是将文件内容存储在特殊的数据库列而不是云服务中。

该实现基于标准的Rails Active Storage服务,并添加了新模型的迁移:一个额外的表,用于在二进制字段中存储Blob内容。该服务根据Active Storage的要求在此表中创建和销毁记录。

因此,该服务一旦安装,便可以通过标准的Rails Active Storage API使用。

https://github.com/TitovDigital/activestorage-database-service

请注意使用数据库存储文件的优缺点。

使用正确的数据库,它将提供完整的ACID支持,并且可以将文件存储和删除包装为事务。在DevOps中,这也容易得多,因为只需配置一项服务即可。

大文件或大流量是危险的情况。两者都会给应用程序和数据库服务器带来不必要的压力。