我们有很多.Net应用程序可以将文件上传到SQL Server(2008)并从中检索它们。我们在大多数地方将文件存储为varbinary(max)。
这当然是一种常见的做法,但我想知道是否有人在节省之前更加努力并压缩文件(即zip),并在检索时解压缩(解压缩)?我们的一些数据库在.mdf文件大小方面达到40-100gb范围,我知道可以修剪一下。
这是一个好习惯吗?任何人都知道性能影响,或者有任何示例代码?
由于 汤姆
答案 0 :(得分:4)
首先,我们需要查看有关问题和答案的评论中显示的其他详细信息:
我测试了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文件)上进行自己的一些采样是明智的,以便更清楚地了解您将真正节省的内容。并且知道您实际期望保存多少应该有助于确定以下哪个选项在给定可用时间/资源的情况下最有意义。
您的选择似乎是:
压缩:在重构现有代码方面,这似乎是最少的努力。压缩和解压缩Web服务器上的文件应该是相当简单的(.Net框架附带库来做Deflate / Inflate以及Gzip / Ungzip),并且DB层不需要进行任何更改(您只需要将现有数据一次性迁移到压缩格式)。在对这个问题的评论中,JonSkeet询问这项努力是否值得。鉴于此选项的努力程度较低,我认为这是明确的是。开发人员时间为50美元/小时(左右),这样的项目可能需要10个小时(包括质量保证),即已支付(预算明智)员工时间500美元。获得新的SAN空间将花费多超过500美元(如果由于某种原因,实施需要20个小时,甚至超过1000美元)并且通常来自另一个预算,需要申请等。
除了MDF文件大小的立即减少之外还有其他好处,即:
修改强>
一些补充说明:
如果将压缩数据存储在数据库中,无论是用于一次性数据迁移还是只是为了能够访问" 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这个问题会给你一个更深入的背景故事,所以我不会在这里复制。
任何人都知道性能影响
当涉及到你所建议的表现时,没有一个答案对每个人都有效。它取决于以下几点:
对上述问题的不同答案将导致对绩效的巨大差异。
如果您在最终用户PC上进行压缩,那么您可能会注意到某些好处;如果数据可以很好地压缩(并且足够快),那么将数据发送到数据库可能比发送未压缩版本花费的时间更少。但是,如果数据无法很好地压缩(或压缩非常缓慢),那么您的最终用户可能会抱怨降低的性能;它可能需要更少的时间将其发送到服务器,但最终用户将注意到的唯一事情是数据被压缩时的加载栏。您可以通过有条件地压缩已知压缩的文件(例如文本文档)来解决这个问题。
如果在Web服务器上执行压缩,然后将其写入数据库,您可能无法在速度方面获得很多好处。服务器通常通过非常快速的连接相互连接(如果它们位于同一个数据中心,通常为100 / 1000mbit连接),并且您已经发生了最可能的瓶颈:用户的上传速度' s网络连接。
此时,您只需在Web服务器上加载更多负载,这可能会更好地为Web应用程序的更多并发用户提供服务。当然,您总是可以将文件上传到临时目录并在非高峰时段执行压缩,但是您已经添加了很多复杂性(如果在压缩文件并将其发送到之前再次请求该文件会怎么样?数据库?)只是为了节省几兆字节的服务器。
此外,每次请求文件时,您都会产生类似的性能成本,因为您必须花时间和处理能力来解压缩它。如果您在很短的时间内收到许多下载文件的请求,那么您的服务器可能会慢慢爬行,尝试解压缩每个人的文件,然后再将其发送到网上。
正如我在开始时所说的那样,没有一个单独的答案对每个人都有效,但如果你考虑所有因素,你可以做出明智的决定,哪些最适合你的环境。