文档存储的推荐位置——数据库中还是其他地方?

19

背景:

我们有一个早期实施的内部文档存储系统。出于某种原因,选择将数据库作为文档的存储机制。

我的问题是:

何为最佳文档存储实践?还有哪些选择?它们的优缺点是什么?答案不需要特定于技术或平台,这更像是一般最佳实践问题。

我的想法:

数据库不适合文档存储。文件系统或第三方文档管理系统可能更加合适。在数据库中存储文档是昂贵的,操作也很慢。这些是否是正确的假设?也许这是最好的方法,但我认为我们有更好的选择。使用Oracle BFILE(指向NAS或SAN上的文档链接)比BLOB / CLOB更好吗?

细节:

  • 文档类型各异(pdf、word、xml)
  • 中间层代码使用.net 2.0 / c#编写
  • 文档以压缩的BLOB形式存储在Oracle 10g数据库中(NAS存储)
  • 文件大小不等
  • 文档数量急剧增长,没有放缓的迹象
  • 峰值时插入通常在每小时数百个左右
  • 检索通常在每小时数千个左右
  • NAS存储和SAN存储可用

更新(从下面的问题):

  • 我的背景是开发
  • 与文件相关的元数据存储在数据库旁边

你是否需要版本控制、审计或复杂的安全结构?你需要将元数据与每个文件关联吗? - Bravax
你可能会想查看https://dev59.com/OnVD5IYBdhLWcg3wXaYd,那个问题涉及到数据库中的图像,但是一些答案可能适用。 - James McMahon
13个回答

14

基于我的经验,我建议将它们保存在数据库中。我们把我们的两个系统都改成了这样。

将它们保存在数据库中意味着:

  • 即使从多台服务器上访问也很容易;
  • 自动备份(而不需要单独设置任务);
  • 不必担心存储空间(因为人们会防止数据库过度填充磁盘,但可能会忘记监控文档存储的位置);
  • 无需复杂的目录结构;

我们曾将文档存储在数据库之外。当文档数量很大时,这将成为一个问题。Linux中的普通目录占用一个块,通常为4K。我们有一个目录的大小为58MB,其中包含了这么多的文件(仅是一个平坦的目录,没有层次结构)。它有那么多的间接块。删除该目录花费了超过一个小时的时间。计算该目录中文件数量花费了几分钟的时间。情况非常糟糕。这是在ext3上发生的。

使用文件系统,你需要:

  • 单独的备份机制(与数据库备份分开);
  • 保持同步(以防止记录存在于数据库中,而文件不存在);
  • 存储层次结构(防止出现上述问题,以免某个目录包含成千上万的文件);
  • 如果需要集群,则需要从其他服务器查看这些文件(因此可能需要NFS或类似的东西)。

这真的很麻烦。对于任何大量文档的情况,我建议不要使用基于文件系统的方式,根据我的经验来看。


1
+1个关于数据库存储的好理由。现在我们只需要一个类似质量的答案来解决文件系统方法。 :-) - Darron
谢谢。就像我说的,这对我们来说有点噩梦般的经历(我们无法在没有停机时间的情况下删除目录!)大多数人似乎喜欢FS方法,如果它被设计得好,它会起作用(我们不会遇到我们所遇到的问题)。但是我们的系统并没有为如此多的文档而设计。 - MBCook
我对使用数据库进行文件存储没有任何问题。但是,只有在团队完全致力于仅在数据库中存储文档并从其他任何地方删除文档的情况下,我才会考虑这样做。但是,您实际上正在创建一个文档管理系统。难道没有现成的文档管理系统吗? - Alan McBee

11

我更倾向于将文档保存在文件系统中,然后在数据库中存储与该文件相关的链接和元数据。

这种方法被证明比其他替代方案更方便、更易于维护,也更经济实惠。


同意。只要备份与数据库备份相似/相同即可。强大而友好。此外,良好的文件夹结构使技术人员轻松查看。 - Stu Andrews
这个答案没有得到支持。为什么评分这么高?它并不糟糕,但也没有什么特别的。 - Joe Soul-bringer
你如何处理文件系统中数以万计的文档,特别是在一个平坦的结构中? - RyanW
我更喜欢这个答案。虽然我不确定成本,但我点赞的原因是我正在向一个已经有大量文档存放在各种地方的移动团队引入一个集中式目录。我们没有实际的方法可以将所有这些文档移动(从原始位置删除)到任何新的存储库中。此外,已经有很多优秀的文档管理系统来管理访问和工作流程;为什么要自己开发呢?你真正需要的只是集中式发现,而不是集中式存储。 - Alan McBee

8
大多数企业级文档管理系统不会将对象文件存储在数据库中。仅仅因为你可以这样做,并不意味着你应该这样做。如果可扩展性和性能对你很重要,而你有一个大型的文档集合,那么你需要非常小心地考虑将对象存储在数据库中。请考虑以下内容:
在文档成像的情况下,2亿个TIFF文件可以被认为是一个相对较大但不是特别巨大的系统。更大规模的系统可能有超过10亿个对象文件。例如,每个双色调TIFF大约20KB,则你需要4TB的对象文件存储空间。你的数据库备份需要多长时间?你的查询需要多长时间?这些对象的访问频率是多少?如果这些对象的访问频率很高,你是否希望你的高端数据库服务器花费全部时间来提供文件服务?如果你有数百万个对象,那么你需要非常小心地设计一个解决方案,其中对象存储在数据库中。
假设你现在的任务是将这2亿个TIFF文件转换为PDF文件。你需要准备好让你的解决方案陷入困境,因为你的数据库服务器会浪费时间为每个对象文件提供服务,然后重新保存结果。
以SharePoint为例,它以在数据库中存储对象而著名。SharePoint也以可扩展性问题而著称。
我的答案:
对于小型系统(<1M个文件),可以考虑将文件存储在数据库中。 对于大型系统(>1M个文件),将文件存储在数据库中是一个错误。

在文件系统级别上存储超过1M个文件的最佳实践是什么?有没有经过生产硬化的解决方案可以使用,而不必重新发明轮子并避免常见陷阱? - yagooar

6

我对将文件存储在数据库本身的最大担忧是管理备份和其他数据库维护操作的大小和复杂性。

缓解这种困难的一种策略(至少在MS SQL中)是创建单独的数据库分区,可能存储在不同的驱动器上。

然后将数据模式分离,使有关文件的元数据位于一个分区中,实际的BLOB文件位于另一个分区中。

这些分区可以根据不同的时间表进行备份,甚至可以单独恢复。


为图像/BLOB数据类型创建单独的文件组,加1。 - DJ.
是的,我确实见过这个问题。分离分区的备份/恢复解决方案与传统解决方案有何不同,并且在实际操作中它如何使问题更容易解决? - Simon Gibbs
按照我上面概述的方式划分分区,可以让你在出现问题时恢复元数据,而无需恢复所有巨大的文件。但是,如果要恢复单个文件,则仍然存在问题,因为您无法仅恢复表中的单个;您必须恢复整个分区(没有第三方工具,如Quest Lightspeed)。 - BradC

5

在数据库中存储文档的唯一限制是技术上的。

关系型数据库旨在成为企业使命关键数据的持久存储。当然,它能够执行该功能的效果因数据库和系统而异。但是,理想情况下关系型数据库ACID属性旨在将其作为所有企业数据的存储。文件系统、版本控制系统和其他本地存储系统可能具有特定优势,但它们并非专门设计用于企业数据存储。

如果您存储的文件属于企业数据 - 如果它们在整个企业中持续使用 - 那么将它们保存在数据库中是合理的。如果您在存储过程中遇到问题,也许DBA可以找到更好的解决方案。出于性能原因,您甚至可能不得不将它们移出数据库,但我认为出于最佳实践的原因,您不应将它们移出数据库。
当然,如果这些文件不是企业数据,如果它们仅用于一个应用程序,那么将它们移出数据库也是有道理的。

3

我曾经把图片存储为BLOBs在数据库中,但第一次批量操作这些图片时就后悔了。如果在文件系统中操作会更容易。而且,正如你所提到的,如果文件存储在文件系统中,检索文档的速度会更快。

我的简单观点是:文件系统应该存储文件,关系型数据库应该存储关系数据。


为文件系统中存储的文件操作提供更好的批处理工具,加1。 - dthrasher

1

将二进制文件存储在文件系统中。创建一个ASP.NET应用程序来进行存储和检索操作。您可以在Web应用程序中使用高级功能(文档版本控制、多层安全等)。我认为这是文档管理行业的共识。

由于您的“文档数量急剧增长”,看起来这正在变成大规模的问题。您可能需要开始寻找第三方现成解决方案(例如http://kofax.com/capture/ - 我对此有丰富的经验!)来为您完成“肮脏的工作”。或者更好的选择是考虑使用SaaS服务,例如这些公司http://www.edocumentsolutionsllc.com/

:-)


0

如果您想要访问文件并进行编辑和重新保存,请将文档存储为 .doc 等文件。

如果您想要实际的历史副本,可以随时检索和再现,请将文档存储为 .pdf 或 .tiff 等文件。

请将有关文件的所有信息(例如日期、作者、位置)存储在数据库中。


0

我通常会将文档的核心信息和文件路径存储在数据库中,但从不存储文档本身。很少需要将整个文档存储在数据库中。

这样可以更灵活地使用这些文档。例如,想要使用分层备份存储和去重机制吗?可以尝试在 Oracle BLOBs 中实现。


0
我唯一能看到将文档存储在数据库中的优点是轻松地将这些文档移动到另一个环境中。除此之外,出于已经提到的所有原因,我不会这样做。

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