在元数据位于SQL数据库中时存储/检索数百万个文件的最佳方法

Sql*_*yan 8 .net vb.net large-data-volumes file-management

我有一个流程,最初将生成3-4百万个PDF文件,并以80K /天的速度继续.它们每个都很小(50K),但我担心的是如何管理我生成的文件总量以便于查找.一些细节:

  1. 一旦生成了文件,我将有一些其他步骤来运行,并且会有一些服务器参与,所以我需要在生成文件时监视这些文件.
  2. 生成后,通过我编写的查找过程,文件将可用.基本上,我需要根据订单号来提取它们,订单号对于每个文件都是唯一的.
  3. 在任何时候,可以重新提交现有订单号,并且生成的文件将需要覆盖原始副本.

最初,我曾计划将这些文件全部写入NAS上的单个目录,但我意识到这可能不是一个好主意,因为它们有数百万个,Windows可能无法正常处理百万文件查找.我正在寻找一些建议:

  1. 单个文件夹好不好?永远不会列出这些文件 - 它们只能使用我已经确定的文件名的System.IO.File来检索.
  2. 如果我做一个文件夹,我可以使用System.IO.DirectoryWatcher查看新文件,即使有那么多文件,还是会因为那么多文件而变得迟钝?
  3. 它们应该作为BLOB存储在SQL Server数据库中吗?由于我需要通过参考值检索它们,这可能更有意义.

谢谢你的想法!

Bra*_*vax 5

要回答您的问题:

  1. 我不会将它们存储在单个文件夹中。有时您会希望查看磁盘上的实际文件,而不是其他方式。
    相反,为什么不将它们存储在单独的目录中,分为1000个批次呢?可能使用ID作为密钥。
  2. 这么多的文件可能会淹没DirectorWatcher,因此有些文件将会丢失。我过去使用过此功能,并且在某个特定点(几百分钟)内使用过,我发现它开始丢失文件。可能对传入文件使用不同的目录,然后每隔一段时间进行处理。然后,这可以触发更新原始文件的过程。
  3. 我不会将文档存储在数据库中,而是将元数据绝对存储在数据库中。


小智 5

您可以轻松地将文件组织到多个文件夹中,而无需通过业务逻辑或每日订单来执行此操作,如果这种排序是“成块的”(一个文件夹中有很多点击,其他文件夹中的点击很少),这尤其好。

最简单的方法是为文件名创建一个唯一的哈希值,这样你可能会得到这样的结果:

sf394fgr90rtfofrpo98tx.pdf
Run Code Online (Sandbox Code Playgroud)

然后把它分解成两个字符的块,你会得到这个:

sf/39/4f/gr/90/rt/fo/fr/po/98/tx.pdf
Run Code Online (Sandbox Code Playgroud)

如您所见,它为您提供了一个可以轻松导航的深层目录树。

使用良好的散列函数,这将非常均匀地分布,并且每个目录永远不会超过 1296 个条目。如果您遇到碰撞(这应该是非常罕见的),只需在末尾添加一个数字:tx.pdf、tx_1.pdf、tx_2.pdf。同样,如此大的散列上的冲突应该是非常罕见的,因此您因此而获得的那种聚集不是问题。

你说这些文件是数字签名的,所以你可能有你需要的以签名字符串形式存在的哈希值。


Phi*_*ley 3

我会将文件分组到特定的子文件夹中,并尝试以某种业务逻辑方式组织它们(子文件夹)。也许是在某一天制作的所有文件?每天的六个小时内?或者每个文件数,我想说最多 1000 个。(可能有一个理想的数字,希望有人会发布它。)

文件是否会过期并被删除?如果是这样,则排序并归档为可删除块。如果没有,我可以成为你们的硬件供应商吗?

对于将文件存储在数据库中,双方都存在争论。

  • 一方面,您可以获得增强的安全性,因为从数据库中提取文件更加困难;另一方面,您的性能可能会较差,因为从数据库中提取文件更加困难。
  • 在数据库中,您不必担心每个文件夹、扇区、NAS 集群等有多少文件——这是数据库的问题,并且可能他们对此有一个很好的实现。另一方面,管理/审查数据会更加困难,因为单个表中会有无数的 blob,而且,嗯,恶心。(您可以根据上述业务逻辑对表进行分区,这将使删除或归档变得更加容易执行。或者可能是分区视图,因为表分区有 1000 个分区的限制。)
  • SQL Server 2008具有FileStream数据类型;我对此了解不多,也许值得研究一下。

最后要担心的一点是保持数据“对齐”。如果数据库将信息存储在文件上以及文件的路径/名称,并且文件被移动,那么您可能会彻底崩溃。