将文件与一段数据相关联的最佳方法是什么?

时间:2009-03-05 21:45:37

标签: database file

我有一个在表格中创建记录的应用程序(火箭科学,我知道)。用户希望将文件(.doc,.xls,.pdf等)与表中的单个记录相关联。

  • 我应该存储的内容 文件在数据库中?不会这样 膨胀数据库?

  • 我应该将文件存储在文件中吗? 服务器,并将路径存储在 数据库?

这样做的最佳方式是什么?

8 个答案:

答案 0 :(得分:10)

我认为你已经准确地捕捉到了解决这个问题的两种最流行的方法。各有利弊:

将文件存储在数据库

大多数rbms支持在db中存储blob(或二进制文件数据,.doc,.xls等)。所以你不是在这里开辟新的领域。

赞成

  • 简化数据备份:您备份拥有所有文件的数据库。
  • 元数据(关于文件的其他列)和文件本身之间的链接是可靠的并且内置到数据库中;所以它是一站式商店,以获取有关您的文件的数据。

缺点

  • 当您将所有二进制数据存储到数据库中时,备份可能很快变成巨大的噩梦。您可以通过将文件保存在单独的数据库中来缓解一些令人头疼的问题。
  • 如果没有DB或DB的接口,就没有简单的方法来获取文件内容来修改或更新它。
  • 一般来说,编写和协调数据上传和存储到数据库与文件系统的比较困难。

将文件存储在FileSystem

这种方法非常简单,您可以将文件本身存储在文件系统中。您的数据库存储对文件位置的引用(以及有关该文件的所有元数据)。这里有一个有用的提示是标准化磁盘上文件的命名方案(不要使用用户提供给你的文件,自己创建一个文件并将它们存储在数据库中)。

赞成

  • 将文件数据与数据库完全分开。
  • 易于维护文件本身(如果您需要更改文件或更新文件),您可以在文件系统中自行维护。您也可以通过新上传从应用程序轻松完成。

缺点

  • 如果您不小心,您的数据库文件可能与文件本身不同步。
  • 安全性可能是一个问题(如果你不小心的话),这取决于你存储文件的位置以及该文件系统是否可供公众使用(通过网络我假设在这里)。

在一天结束时,我们选择了文件系统路径。一旦我们锁定任何漏洞并将文件流出(而不是直接从文件系统中提供服务),它更容易实现快速,易于备份,非常安全。在两个不同的政府申请中,它在大约6年的时间里以相同的格式运作。

Ĵ

答案 1 :(得分:4)

在数据库中存储二进制文件或BLOB的程度将高度依赖于您使用的DBMS。

如果在文件系统上存储二进制文件,则需要考虑在文件名冲突的情况下会发生什么,您尝试存储两个具有相同名称的不同文件 - 如果这是有效操作。因此,除了文件系统中文件所在位置的引用外,您还可能需要存储原始文件名。

此外,如果要存储大量文件,请注意将所有文件存储在一个文件夹中的可能性能命中。 (您没有指定操作系统,但是您可能需要查看NTFS的this问题或ext3的this参考。)

我们有一个系统必须在文件系统上存储数千个文件,在文件系统上我们担心任何一个文件夹中的文件数量(我认为它可能是FAT32)。

我们的系统会添加一个新文件,并为其生成一个MD5校验和(十六进制)。它需要前两个字符,并使第一个文件夹,接下来的两个字符,并使第二个文件夹作为第一个文件夹的子文件夹,然后将下两个作为第三个文件夹作为第一个文件夹的子文件夹第二个文件夹。

这样,我们最终得到了一个三级文件夹,文件分散得很好,所以没有一个文件夹填满太多。

如果我们仍然之后发生文件名冲突,那么我们只需将“_ n ”添加到文件名(扩展名之前),其中 n 只是一个递增的数字,直到我们得到一个不存在的名称(即便如此,我认为我们创建了原子文件,只是为了确定)。

当然,您需要使用工具偶尔将数据库记录与文件系统进行比较,标记任何丢失的文件并清理数据库记录不再存在的任何孤立文件。

答案 2 :(得分:2)

将数据库用于数据,将文件系统用于文件。只需将文件路径存储在数据库中即可。

此外,您的网络服务器可能比应用程序代码更有效地提供文件(为了将文件从数据库传输回客户端)。

答案 3 :(得分:2)

将路径存储在数据库中。这可以防止数据库膨胀,还允许您单独备份外部文件。您也可以更轻松地重新定位它们;只需将它们移动到新位置,然后更新数据库。

要记住的另一件事是:为了使用您提到的大多数文件类型,您最终必须:

  • 查询数据库以获取blob中的文件内容
  • 将blob数据写入磁盘文件
  • 启动应用程序以打开/编辑您刚刚创建的文件
  • 将文件从磁盘读回blob
  • 使用新内容更新数据库

所有这些都与:

相反
  • 从数据库中读取文件路径
  • 启动应用以打开/编辑/无论文件

我更喜欢第二组步骤,我自己。

答案 4 :(得分:2)

如果您确定知道这些文件的大小不会失控,那么您应该只在数据库中存储文件。

我使用我们的数据库存储小横幅图像,我总是知道它们的大小。您的数据库将存储指向行内数据的指针,然后将数据本身插入其他位置,因此它不一定会影响速度。

如果有太多未知数,那么使用文件系统是更安全的路径。

答案 5 :(得分:2)

最好的解决方案是将文档放入数据库中。这简化了所有链接和备份以及恢复问题 - 但它可能无法解决基本的“我们只想指向用户可能拥有的文件服务器上的文档”。

这完全取决于(最终)实际用户要求。

我的建议是将它们全部放在数据库中,这样你就可以保留对它们的控制权。将它们保留在文件系统中会使它们被删除,移动,ACL或其他数百种其他任何可能导致链接无关甚至破坏的更改。

数据库膨胀只是一个问题,如果你没有为它调整大小。做一些测试,看看它有什么影响。磁盘上的100GB文件可能与数据库中的相同文件一样大。

答案 6 :(得分:1)

我会尝试将它全部存储在数据库中。没有做到。但如果没有。文件名与磁盘上的文件不同步的风险很小。那你就有一个大问题。

答案 7 :(得分:0)

现在,对于完全不在墙上的建议 - 您可以考虑将二进制文件存储为attachments文档数据库中的CouchDB。这样可以避免文件名冲突问题,因为您将生成的UID用作每个文档ID(您将在RDBMS中存储的内容),并且实际附件的文件名与文档一起保存。

如果您正在构建基于Web的系统,那么CouchDB使用REST over HTTP的事实也可以被利用。而且,还有可以证明有用的复制工具。

当然,尽管有some已经在野外使用它,但CouchDB仍在孵化中。