我有一个在表格中创建记录的应用程序(火箭科学,我知道)。用户希望将文件(.doc,.xls,.pdf等)与表中的单个记录相关联。
我应该存储的内容 文件在数据库中?不会这样 膨胀数据库?
我应该将文件存储在文件中吗? 服务器,并将路径存储在 数据库?
这样做的最佳方式是什么?
答案 0 :(得分:10)
我认为你已经准确地捕捉到了解决这个问题的两种最流行的方法。各有利弊:
大多数rbms支持在db中存储blob(或二进制文件数据,.doc,.xls等)。所以你不是在这里开辟新的领域。
这种方法非常简单,您可以将文件本身存储在文件系统中。您的数据库存储对文件位置的引用(以及有关该文件的所有元数据)。这里有一个有用的提示是标准化磁盘上文件的命名方案(不要使用用户提供给你的文件,自己创建一个文件并将它们存储在数据库中)。
在一天结束时,我们选择了文件系统路径。一旦我们锁定任何漏洞并将文件流出(而不是直接从文件系统中提供服务),它更容易实现快速,易于备份,非常安全。在两个不同的政府申请中,它在大约6年的时间里以相同的格式运作。
Ĵ
答案 1 :(得分:4)
在数据库中存储二进制文件或BLOB的程度将高度依赖于您使用的DBMS。
如果在文件系统上存储二进制文件,则需要考虑在文件名冲突的情况下会发生什么,您尝试存储两个具有相同名称的不同文件 - 如果这是有效操作。因此,除了文件系统中文件所在位置的引用外,您还可能需要存储原始文件名。
此外,如果要存储大量文件,请注意将所有文件存储在一个文件夹中的可能性能命中。 (您没有指定操作系统,但是您可能需要查看NTFS的this问题或ext3的this参考。)
我们有一个系统必须在文件系统上存储数千个文件,在文件系统上我们担心任何一个文件夹中的文件数量(我认为它可能是FAT32)。
我们的系统会添加一个新文件,并为其生成一个MD5校验和(十六进制)。它需要前两个字符,并使第一个文件夹,接下来的两个字符,并使第二个文件夹作为第一个文件夹的子文件夹,然后将下两个作为第三个文件夹作为第一个文件夹的子文件夹第二个文件夹。
这样,我们最终得到了一个三级文件夹,文件分散得很好,所以没有一个文件夹填满太多。
如果我们仍然之后发生文件名冲突,那么我们只需将“_ n ”添加到文件名(扩展名之前),其中 n 只是一个递增的数字,直到我们得到一个不存在的名称(即便如此,我认为我们创建了原子文件,只是为了确定)。
当然,您需要使用工具偶尔将数据库记录与文件系统进行比较,标记任何丢失的文件并清理数据库记录不再存在的任何孤立文件。
答案 2 :(得分:2)
将数据库用于数据,将文件系统用于文件。只需将文件路径存储在数据库中即可。
此外,您的网络服务器可能比应用程序代码更有效地提供文件(为了将文件从数据库传输回客户端)。
答案 3 :(得分:2)
将路径存储在数据库中。这可以防止数据库膨胀,还允许您单独备份外部文件。您也可以更轻松地重新定位它们;只需将它们移动到新位置,然后更新数据库。
要记住的另一件事是:为了使用您提到的大多数文件类型,您最终必须:
所有这些都与:
相反我更喜欢第二组步骤,我自己。
答案 4 :(得分:2)
如果您确定知道这些文件的大小不会失控,那么您应该只在数据库中存储文件。
我使用我们的数据库存储小横幅图像,我总是知道它们的大小。您的数据库将存储指向行内数据的指针,然后将数据本身插入其他位置,因此它不一定会影响速度。
如果有太多未知数,那么使用文件系统是更安全的路径。
答案 5 :(得分:2)
最好的解决方案是将文档放入数据库中。这简化了所有链接和备份以及恢复问题 - 但它可能无法解决基本的“我们只想指向用户可能拥有的文件服务器上的文档”。
这完全取决于(最终)实际用户要求。
我的建议是将它们全部放在数据库中,这样你就可以保留对它们的控制权。将它们保留在文件系统中会使它们被删除,移动,ACL或其他数百种其他任何可能导致链接无关甚至破坏的更改。
数据库膨胀只是一个问题,如果你没有为它调整大小。做一些测试,看看它有什么影响。磁盘上的100GB文件可能与数据库中的相同文件一样大。
答案 6 :(得分:1)
我会尝试将它全部存储在数据库中。没有做到。但如果没有。文件名与磁盘上的文件不同步的风险很小。那你就有一个大问题。
答案 7 :(得分:0)
现在,对于完全不在墙上的建议 - 您可以考虑将二进制文件存储为attachments文档数据库中的CouchDB。这样可以避免文件名冲突问题,因为您将生成的UID用作每个文档ID(您将在RDBMS中存储的内容),并且实际附件的文件名与文档一起保存。
如果您正在构建基于Web的系统,那么CouchDB使用REST over HTTP的事实也可以被利用。而且,还有可以证明有用的复制工具。
当然,尽管有some已经在野外使用它,但CouchDB仍在孵化中。