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

时间:2012-11-02 20:25:58

标签: asp.net sql sql-server-2008 compression sharpziplib

现在我们有一个数据库表(SQL Server 2008 R2),它在图像类型列中存储上传的文件(PDF,DOC,TXT等)。用户从ASP.NET应用程序上载此文件。我的项目是要掌握这张桌子的大小,我一路上想出了几个问题。

  1. 在数据库方面,我发现图像列类型据说有些折旧?我可以获得切换到varbinary(max)的任何好处,或者我应该说varbinary(5767168),因为这是我的文件大小上限,或者我也可以让它保留为图像类型,只要空间效率是关注?

  2. 在应用程序端,我想压缩字节数组。微软内置的GZip有时会使文件更大而不是更小。我切换到SharpZipLib,这要好得多,但我偶尔会遇到同样的问题。在我大规模实施之前,有没有办法找出平均文件压缩节省?我很难找到他们使用的基础算法。

  3. 是否值得编写我自己的霍夫曼代码算法,或者在有时会出现比原始文件更大的压缩文件时会出现同样的问题?

  4. 作为参考,如果重要,这是我的应用程序中的代码:

        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();
        }
    

    提前感谢您的帮助。 :)

2 个答案:

答案 0 :(得分:3)

这不是一个字节数组,那是一个BLOB。 10年前,您将使用IMAGE数据类型。

这些天,使用VARBINARY(MAX)效率更高 我真的建议人们使用FILESTREAM for VarBinary(Max),因为它可以很容易地备份数据库(没有blob)。

请记住,使用原生格式(无压缩)将允许全文搜索..如果您考虑它,这是非常不可思议的。你必须从Adobe安装一些iFilter才能在PDF中搜索..但它是一个杀手级的功能,没有它我就活不下去。

答案 1 :(得分:1)

我讨厌成为一个混蛋并回答我自己的问题,但我认为我会将我的发现总结为一个完整的答案,以便其他任何希望在数据库中空间有效地存储文件/图像数据的人:

*使用varbinary(MAX)与Image?

使用varbinary(MAX)的原因很多,但其中最重要的是不推荐使用Image,而在将来的SQL版本中,它将被完全删除。没有开始任何新的项目只是将未来的问题扼杀在萌芽状态。

根据此问题中的信息:SQL Server table structure for storing a large number of images,varbinary(MAX)可以在其上使用更多操作。

Varbinary(MAX)很容易通过使用SQL参数从.NET应用程序流式传输。负值是'MAX'长度。像这样:

SQLCommand1.Parameters.Add("@binaryValue", SqlDbType.VarBinary, -1).Value = compressedBytes;

*使用什么压缩算法?

我真的不太接近这个问题的正确答案。我使用了ICSharpCode.SharpZipLib.Gzip,发现它比内置的压缩​​函数具有更好的性能,只需在一堆东西上运行并比较它。

我的结果:

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