在数据库表中存储字节数组的最节省空间的方法-ASP.NET

在数据库表中存储字节数组的最节省空间的方法-ASP.NET,asp.net,sql,sql-server-2008,compression,sharpziplib,Asp.net,Sql,Sql Server 2008,Compression,Sharpziplib,现在我们有一个数据库表(SQLServer2008R2),它在图像类型列中存储上传的文件(PDF、DOC、TXT等)。用户从ASP.NET应用程序上载此文件。我的项目是要弄清楚这张桌子增长的规模,在这过程中我提出了几个问题 在数据库方面,我发现图像列类型被认为有点贬值了?切换到varbinary(max)会给我带来什么好处,或者我应该说varbinary(5767168),因为这是我的文件大小上限,或者我最好还是让它作为一种图像类型,就空间效率而言 在应用程序方面,我想压缩字节数组。微软内置的G

现在我们有一个数据库表(SQLServer2008R2),它在图像类型列中存储上传的文件(PDF、DOC、TXT等)。用户从ASP.NET应用程序上载此文件。我的项目是要弄清楚这张桌子增长的规模,在这过程中我提出了几个问题

  • 在数据库方面,我发现图像列类型被认为有点贬值了?切换到varbinary(max)会给我带来什么好处,或者我应该说varbinary(5767168),因为这是我的文件大小上限,或者我最好还是让它作为一种图像类型,就空间效率而言

  • 在应用程序方面,我想压缩字节数组。微软内置的GZip有时会使文件变大而不是变小。我改用了SharpZipLib,它比SharpZipLib好得多,但我仍然偶尔遇到同样的问题。在大规模实施之前,有没有办法找出平均文件压缩节省量?我很难找出他们使用的底层算法是什么

  • 值得我自己编写一个哈夫曼代码算法吗?或者,当压缩文件有时比原始文件大时,会出现同样的问题吗

  • 作为参考,如果有问题,我的应用程序中的代码如下:

        using ICSharpCode.SharpZipLib.GZip;
    
        private static byte[] Compress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
    
            using (GZipOutputStream gzip = new GZipOutputStream(output))
            {
                gzip.IsStreamOwner = false;
                gzip.Write(data, 0, data.Length);
                gzip.Close();
            }
            return output.ToArray();
        }
    
        private static byte[] Decompress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
    
            using (GZipInputStream gzip = new GZipInputStream(input))
            {
                byte[] buff = new byte[64];
                int read = gzip.Read(buff, 0, buff.Length);
    
                while (read > 0)
                {
                    output.Write(buff, 0, read);
                    read = gzip.Read(buff, 0, buff.Length);
                }
    
                gzip.Close();
            }
            return output.ToArray();
        }
    

    提前感谢您的帮助。:)

    那不是字节数组,那是一个BLOB。10年前,您可能会使用图像数据类型

    现在,使用VARBINARY(MAX)效率更高 我真的建议人们使用FILESTREAM for VarBinary(Max),因为它使备份数据库(没有blob)变得非常容易


    请记住,使用本机格式(无压缩)将允许全文搜索。。如果你仔细想想,这真是难以置信。您必须从Adobe安装一些iFilter,以便在PDF中搜索。。但它是一个杀手级功能,没有它我无法生存。

    这不是字节数组,而是一个BLOB。10年前,您可能会使用图像数据类型

    现在,使用VARBINARY(MAX)效率更高 我真的建议人们使用FILESTREAM for VarBinary(Max),因为它使备份数据库(没有blob)变得非常容易


    请记住,使用本机格式(无压缩)将允许全文搜索。。如果你仔细想想,这真是难以置信。您必须从Adobe安装一些iFilter,以便在PDF中搜索。。但它是一个杀手级功能,我不能没有它。

    我不想成为一个混蛋,回答我自己的问题,但我想我应该将我的发现总结成一个完整的答案,供任何希望在数据库中高效存储文件/图像数据的人使用:

    *使用varbinary(最大值)与Image?

    使用varbinary(MAX)的原因有很多,但最重要的一个原因是映像已被弃用,在SQL的未来版本中,它将被完全删除。不启动任何新的项目只是将未来的问题扼杀在萌芽状态

    根据这个问题中的信息:,varbinary(MAX)有更多的操作可供使用

    Varbinary(MAX)很容易通过使用SQL参数从.NET应用程序流式传输。负数表示“最大”长度。像这样:

    SQLCommand1.Parameters.Add("@binaryValue", SqlDbType.VarBinary, -1).Value = compressedBytes;
    
    *使用什么压缩算法?

    在这一点上,我真的离一个像样的答案不远了。我使用了ICSharpCode.SharpZipLib.Gzip,通过在一堆东西上运行它并进行比较,发现它比内置的压缩函数具有更好的性能

    我的结果:


    我将我的总文件大小减少了大约20%。不幸的是,我拥有的很多文件都是PDF文件,它们压缩得不好,但仍然有一些好处。(显然)对于已经压缩的文件类型来说,运气不太好。

    我不想做一个傻子,回答我自己的问题,但我想我应该将我的发现总结成一个完整的答案,供任何希望在数据库中高效存储文件/图像数据的人使用:

    *使用varbinary(最大值)与Image?

    使用varbinary(MAX)的原因有很多,但最重要的一个原因是映像已被弃用,在SQL的未来版本中,它将被完全删除。不启动任何新的项目只是将未来的问题扼杀在萌芽状态

    根据这个问题中的信息:,varbinary(MAX)有更多的操作可供使用

    Varbinary(MAX)很容易通过使用SQL参数从.NET应用程序流式传输。负数表示“最大”长度。像这样:

    SQLCommand1.Parameters.Add("@binaryValue", SqlDbType.VarBinary, -1).Value = compressedBytes;
    
    *使用什么压缩算法?

    在这一点上,我真的离一个像样的答案不远了。我使用了ICSharpCode.SharpZipLib.Gzip,通过在一堆东西上运行它并进行比较,发现它比内置的压缩函数具有更好的性能

    我的结果:


    我将我的总文件大小减少了大约20%。不幸的是,我拥有的很多文件都是PDF文件,它们压缩得不好,但仍然有一些好处。对于已经压缩的文件类型(显然)运气不太好。

    对于SQL Server/这类问题还不够好,但我听说资源通常不会持久化到数据库本身(特别是对于大型文件之类的问题),仅引用WebServer上的位置。您可能需要考虑为压缩算法设置一个单独的列。这样,随着时间的推移,您可以针对不同的文件类型使用不同的算法,或者请注意,如果压缩只会导致数据增长,则不使用压缩。Clockwork-Muse,如果文件在将来某个时候移动,则存在坏链接的风险。除了一个程序员知道那些特定的文件不应该被移动之外,你没有任何连接链接和文件的东西。也许可以喝点酒