代码之家  ›  专栏  ›  技术社区  ›  insane.dreamer

Rails:在数据库中存储二进制文件[关闭]

  •  11
  • insane.dreamer  · 技术社区  · 15 年前

    使用Rails,是否有理由将附件(可能是任何时间的文件)存储在文件系统中而不是数据库中?对于我来说,数据库似乎更简单,不需要担心文件系统路径、结构等,只需查看blob字段即可。但大多数人似乎使用的是文件系统,这让我猜测这样做肯定有一些好处,而我没有得到,或者有一些缺点,使用数据库进行这样的存储。(在本例中,我使用的是Postgres)。

    6 回复  |  直到 15 年前
        1
  •  28
  •   easel    15 年前

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

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

    要记住的一些注意事项:

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

    2. 文件通常很大。大型数据库当然是可行的,但它们备份起来缓慢、不方便等等。为什么不必备份就让数据库变得庞大呢?

    3. 与2.非常相似,将文件复制到多台机器上非常容易。假设您运行的是一个集群,您可以定期地将文件系统从主计算机同步到从计算机,并使用标准的静态HTTP服务。显然,数据库也可以集群化,这并不一定是直观的。

    4. 在3的另一面,如果您已经对数据库进行了集群,那么除了管理复杂性之外,还必须处理集群文件。我会说,这是考虑在数据库中存储文件的一个原因。

    5. 数据库中的BLOB数据通常是不透明的。你不能过滤它,不能按它排序,也不能按它分组。这会降低存储在数据库中的价值。

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

    7. 无障碍。文件系统中的文件可以使用常规工具打开。vi,photoshop,word,无论你需要什么。这很方便。你要怎么从blob字段中打开那个Word文档?

    8. 权限。文件系统有权限,它们可能是后端的痛点。相反,它们可能对您的应用程序有用。如果您利用7的优势,那么权限会让您非常痛苦,因为几乎可以保证您的Web服务器以不同于应用程序的权限运行。

    9. 正在缓存(来自下面的Sarah Mei)。在客户端,这会影响到上面的HTTP问题(您还记得正确设置生存时间吗?)在服务器端,文件系统上的文件是一个非常好理解和优化的访问模式。大型blob字段可能会被数据库优化,也可能不会得到很好的优化,而且几乎可以保证从数据库到Web服务器的额外网络访问。

    简而言之,人们倾向于将文件系统用于文件,因为他们最支持类似文件的习惯用法。不过,您没有必要这样做,文件系统越来越像数据库,所以最终看到完全收敛一点也不奇怪。

        2
  •  6
  •   Dan L    13 年前

    对于将文件系统用于文件,有一些好的建议,但是这里还有一些其他的事情要考虑。如果您要存储敏感或安全的文件/附件,那么使用数据库确实是唯一的方法。我已经构建了一些应用程序,这些应用程序的数据不能被输出到文件中。出于安全考虑,必须将其放入数据库。如果没有适当的安全措施,您不能将它保存在文件系统中,供服务器/计算机上的用户查看或使用。使用像Oracle这样的高级数据库,您可以非常紧密地锁定数据,并确保只有适当的用户可以访问该数据。

    但其他的观点是非常有效的。如果你只是做一些像虚拟人物图像或非敏感信息之类的事情,文件系统对于大多数插件系统来说通常更快更方便。

    数据库非常容易设置,可以将文件发送回去;它的工作要多一些,但如果你知道你在做什么,只需要几分钟。所以,是的,文件系统是更好的总体方法,IMO,但是当安全性或敏感数据是主要问题时,DB是唯一可行的选择。

        3
  •  2
  •   Sarah Mei    15 年前

    埃里克的回答很好。我还要补充一点,如果您想进行任何缓存,那么缓存静态文件比缓存数据库内容更容易也更简单。

        4
  •  2
  •   Sfynx    13 年前

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

        5
  •  0
  •   August Lilleaas    15 年前

    如果使用插件,例如 Paperclip 你也不用担心任何事。这里有一个叫做文件系统的东西,文件应该放在这里。仅仅因为这有点困难并不意味着你应该把你的文件放错地方。使用回形针(或其他类似的插件)并不难。所以,gogo文件系统!

        6
  •  0
  •   Paul T.    6 年前

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

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

    因此,此服务一旦安装,就可以通过标准Rails活动存储API使用。

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

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

    有了正确的数据库,它将提供全面的ACID支持,并可以将文件存储和删除打包成事务。在DevOps中,它也更容易配置,因为需要配置的服务更少。

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