.Net:将压缩文件保存到SQL Server?

时间:2014-08-15 19:59:41

标签: .net sql-server

我们有很多.Net应用程序可以将文件上传到SQL Server(2008)并从中检索它们。我们在大多数地方将文件存储为varbinary(max)。

这当然是一种常见的做法,但我想知道是否有人在节省之前更加努力并压缩文件(即zip),并在检索时解压缩(解压缩)?我们的一些数据库在.mdf文件大小方面达到40-100gb范围,我知道可以修剪一下。

这是一个好习惯吗?任何人都知道性能影响,或者有任何示例代码?

由于 汤姆

3 个答案:

答案 0 :(得分:4)

首先,我们需要查看有关问题和答案的评论中显示的其他详细信息:

  1. 由于企业存储的高成本,需要节省空间
  2. 文件类型为:"主要是pdf' s,word docs,excel文件......例如办公室文件。还有一些重要的工程文件,如cad"
  3. 有数千个文件
  4. 许多文件是1-3 Mb
  5. 我测试了1 MB到17 MB的PDF文件,最多可以获得25%的压缩率,而大多数似乎都在10%到15%左右。就Microsoft Office文件而言,如果您正在讨论Office 2007之前的格式(即不以" x"结尾的扩展名)或更新的格式(即以&#结尾的扩展名),它会产生相当大的差异。 34; X&#34)。较新的格式(例如" .docx"," .xlsx"等)已经是一个压缩文件,所以你不会在那里获得任何积蓄(为了你自己看看) :复制/粘贴任何办公室文档,其扩展名以" x"结尾,将该副本重命名为" zip"而不是" docx"或者无论哪个,然后双击它)。我不记得有多少CAD图纸会压缩,但我怀疑至少和PDF图片一样多。

    因此,假设每个3 MB的2000个文件是6 GB。 10%的平均压缩将为您节省600 MB。在您的文件(尤其是CAD文件)上进行自己的一些采样是明智的,以便更清楚地了解您将真正节省的内容。并且知道您实际期望保存多少应该有助于确定以下哪个选项在给定可用时间/资源的情况下最有意义。

    您的选择似乎是:

    1. 压缩:在重构现有代码方面,这似乎是最少的努力。压缩和解压缩Web服务器上的文件应该是相当简单的(.Net框架附带库来做Deflate / Inflate以及Gzip / Ungzip),并且DB层不需要进行任何更改(您只需要将现有数据一次性迁移到压缩格式)。在对这个问题的评论中,JonSkeet询问这项努力是否值得。鉴于此选项的努力程度较低,我认为这是明确的。开发人员时间为50美元/小时(左右),这样的项目可能需要10个小时(包括质量保证),即已支付(预算明智)员工时间500美元。获得新的SAN空间将花费超过500美元(如果由于某种原因,实施需要20个小时,甚至超过1000美元)并且通常来自另一个预算,需要申请等。

      除了MDF文件大小的立即减少之外还有其他好处,即:

      1. 从磁盘读取和写入的所有数据都通过缓冲池。您需要读取和写入这些文件的8k数据页面越多,您的真实应用程序数据就会越频繁地被推出并需要再次从磁盘读取(这是很慢的,否则我们就不会有读/写缓存!)。这会降低您的Page Life Expectancy。
      2. 备份更小!数据越小,备份文件越小。备份和恢复的数据越小,两种操作都越快。
      3. 访问速度更快(通常情况下)。磁盘是系统中最慢的部分,因此如果您可以少访问磁盘,那么通常会有净增益,因为CPU通常可以比磁盘读取/写入数据更快地压缩/解压缩数据。当然,只有使用您的数据和文件在您的系统上进行测试才能证明,但是有一个很好的理由是Microsoft在ROW或PAGE级别为从SQL Server 2008开始的索引包含内置数据压缩。)
    2. FILESTREAM http://technet.microsoft.com/en-us/library/bb933993(v=sql.100).aspx这需要花费更多精力,但会将文件移出MDF文件。如果本地文件共享也在SAN上,您可以考虑组合压缩文件以及使用FILESTREAM将它们从MDF文件中删除。
    3. 远程Blob存储(RBS)http://msdn.microsoft.com/en-us/library/gg316768.aspx这是一个附加功能,您需要单独下载,但似乎是为这种情况而设计的(在更便宜的地方存储外部文件)存储)。与上述两个选项不同,这个可能在备份数据库时不备份外部文件,并且需要辅助备份(当然不是不可能)。在该主RBS页面的底部链接了white paper(从第40页的底部开始)解释了备份选项。 MSDN文档显示了从SQL Server 2008 R2开始的功能,但我没有看到任何迹象表明它在SQL Server 2008中不起作用。
    4. 修改
      一些补充说明:

      1. 如文档中所述, FILESTREAM 选项的一个非常好的好处是它会跳过缓冲池,因此数据的大小在性能方面不是问题(即Page Life Expectancy)。
      2. 如果进行压缩(这可能是一个好主意,不管任何其他选项,因为它可以与它们中的任何一个结合使用),那么选择更通用的方法可能是最好的。这意味着,如果使用.Net框架选项 - Inflate / Deflate或Gzip / Ungzip - 使用Gzip / Ungzip可能更好,因为它更容易找到处理该格式的工具。
      3. 如果将压缩数据存储在数据库中,无论是用于一次性数据迁移还是只是为了能够访问" raw"数据库层上的数据(并且不需要将某些内容移动到应用层,只是为了访问"真实"数据),您可以为Gzip / Ungzip实现SQL CLR功能。如果不确定如何完成此操作,各个站点有很多示例,或者您只需下载并使用SQL#中的[Util_Gzip]和[Util_GUnzip]函数(或[Util_Deflate]和[Util_Inflate])(其中)我是作者,但这些功能在免费版本中可用。在简单的层面上,可以通过执行类似以下的操作来完成一次性数据迁移:

        UPDATE tbl
        SET    tbl.VarBinaryField = SQL#.Util_GZip(tbl.VarBinaryField)
        FROM   SchemaName.TableName tbl
        WHERE  tbl.ID BETWEEN @StartID AND @EndID -- do small batches at a time
        

答案 1 :(得分:3)

这是一个好习惯吗?并不是的。更好的解决方案是将文件存储在文件系统上,并在数据库中保存指向该文件的指针。

与关系纯粹主义者交谈时,这个问题是一个痛点。从他们的角度来看,不应将非结构化数据存储在数据库中。 Microsoft已使用FileStream数据类型解决了此问题。简而言之,它将文件存储在文件系统上而不是mdf文件中。它存储指向文件的指针,然后允许服务器检索,替换,删除等文件。

查看MS documentation here

  

FILESTREAM通过将varbinary(max)二进制大对象(BLOB)数据存储为文件系统上的文件,将SQL Server数据库引擎与NTFS文件系统集成在一起。 Transact-SQL语句可以插入,更新,查询,搜索和备份FILESTREAM数据。 Win32文件系统接口提供对数据的流式访问。

答案 2 :(得分:1)

  

这是一个好习惯吗?

这是一个备受争议的话题。 Another answer这个问题会给你一个更深入的背景故事,所以我不会在这里复制。

  

任何人都知道性能影响

当涉及到你所建议的表现时,没有一个答案对每个人都有效。它取决于以下几点:

  • 您从此表中插入/检索记录的频率是多少?
  • 执行压缩/解压缩的位置?在服务器上,还是在客户端上?
  • 如果在客户端上执行压缩,客户端是Web服务器还是最终用户PC?

对上述问题的不同答案将导致对绩效的巨大差异。

如果您在最终用户PC上进行压缩,那么您可能会注意到某些好处;如果数据可以很好地压缩(并且足够快),那么将数据发送到数据库可能比发送未压缩版本花费的时间更少。但是,如果数据无法很好地压缩(或压缩非常缓慢),那么您的最终用户可能会抱怨降低的性能;它可能需要更少的时间将其发送到服务器,但最终用户将注意到的唯一事情是数据被压缩时的加载栏。您可以通过有条件地压缩已知压缩的文件(例如文本文档)来解决这个问题。

如果在Web服务器上执行压缩,然后将其写入数据库,您可能无法在速度方面获得很多好处。服务器通常通过非常快速的连接相互连接(如果它们位于同一个数据中心,通常为100 / 1000mbit连接),并且您已经发生了最可能的瓶颈:用户的上传速度' s网络连接。

此时,您只需在Web服务器上加载更多负载,这可能会更好地为Web应用程序的更多并发用户提供服务。当然,您总是可以将文件上传到临时目录并在非高峰时段执行压缩,但是您已经添加了很多复杂性(如果在压缩文件并将其发送到之前再次请求该文件会怎么样?数据库?)只是为了节省几兆字节的服务器。

此外,每次请求文件时,您都会产生类似的性能成本,因为您必须花时间和处理能力来解压缩它。如果您在很短的时间内收到许多下载文件的请求,那么您的服务器可能会慢慢爬行,尝试解压缩每个人的文件,然后再将其发送到网上。

正如我在开始时所说的那样,没有一个单独的答案对每个人都有效,但如果你考虑所有因素,你可以做出明智的决定,哪些最适合你的环境。