|
|
|
|
|
Упаковываем данныеРеляционные базы данных подразумевают наличие специального хранилища для данных, и большинство типов данных сохраняется без проблем, хотя бывают и исключения. Например, одна из таких ситуаций возникает, когда приходится часто сжимать бинарные данные, чтобы значительно сократить их объем. Если требуется хранить очень много бинарных данных, их компрессия может существенно уменьшить расходы на запоминающие устройства. Несмотря на то что SQL Server не предоставляет встроенных возможностей компрессии, их можно добавить в SQL Server 2005, опираясь на Common Language Runtime (CLR). Рассмотрим способы сжатия данных в SQL Server 2005 и то, какую пользу можно извлечь из нового типа данных — varbinary(max), который приходит на смену весьма неудобному типу данных image. Ознакомившись с приведенными в этой статье примерами, вы научитесь сжимать данные SQL Server и узнаете, как применить код Windows .NET Framework для усиления влияния SQL Server 2005. Обзор возможностей и первые шаги Для того чтобы сжать данные перед сохранением в базу и привести в первоначальный вид после извлечения из базы, разработчикам годами приходилось изобретать собственные хитроумные решения. Некоторые сведения по этому вопросу приведены во врезке «Основы компрессии». Сильно упрощает решение подобных задач .NET Framework 1.1. В этой платформе предусмотрено пространство имен java.util.zip, с которым связаны методы архивирования и разархивирования данных. Например, в этой версии Framework можно создавать интерфейсные классы для непрямого вызова java.util.zip из языков .NET, таких как VB.NET и C#. Но инфраструктура .NET Framework 2.0, являющаяся частью SQL Server 2005 и Visual Studio (VS) 2005, уже содержит пространство имен System.IO.Compression. Использование методов этого пространства имен делает процесс компрессии и декомпрессии данных очень удобным. Пространство имен System.IO.Compression, доступное во всех языках .NET, предоставляет два класса для компрессии и декомпрессии данных: DeflateStream и GzipStream. В DeflateStream применен алгоритм DEFLATE (в том виде, в каком он определен в документе RFC 1951). В GzipStream реализован формат gzip (определенный в RFC 1952), предназначенный для сжатия единичного файла и также основанный на алгоритме DEFLATE. DeflateStream и GzipStream, как следует из названия, работают с потоками данных. А потоки — это не просто серии байтов, это объекты, дополненные методами для манипулирования другими объектами. Кратко остановимся на тех действиях, которые необходимо выполнить при создании любой программы компрессии, а затем перейдем к конкретным примерам. Сначала нужно добавить операторы Visual Basic (VB) Imports или using в C# для пространства имен System.IO и System.IO.Compression: ' VB Imports statements Imports System.IO _ ' for Stream object Imports System.IO.Compression _ ' for DeflateStream and _ GZipStream // C# code using System.IO; // for Stream object using System.IO.Compression; // for DeflateStream and GZipStream Текст кода разбит на несколько строк из-за особенностей форматирования статьи в журнале. Кроме того, для значений параметров и выходных значений функций нужно использовать собственный для SQL Server тип данных SqlBytes. SqlBytes является частью пространства имен System.Data.SqlType, которое для собственных типов данных SQL Server 2005 предоставляет соответствующие классы. Согласно документации по .NET, эти классы «являются более защищенной и быстрой альтернативой типам данных, имеющимся в .NET [CLR]». Дополнительное удобство предоставляет реализованный в пространствах имен SqlType интерфейс Inullable, который поддерживает актуальное «пустое значение». Использование собственных типов данных SQL Server, помимо прочего, избавляет от проблем преобразования типов. Внутри функций SQL CLR, конечно, можно использовать общие типы данных .NET, такие как массив Byte, например, но среда исполнения все равно будет конвертировать типы данных .NET в соответствующие типы SqlType. Преобразование типов означает как бы небольшой штраф в терминах производительности и не позволяет исключить возможные ошибки перевода. Так, при первом написании функции CompressBytes мы использовали массивы Byte. Работая с готовым кодом в SQL Server 2005, мы обнаружили, что среда исполнения конвертирует массивы Byte в varbinary(8000). Этот неудачный перевод одного типа данных в другой препятствовал работе с документами размером более 8 Кбайт. Для компрессии данных нужно написать не занимающую много места пользовательскую функцию (UDF) типа SqlBytes: Public Shared Function _ CompressBytes(ByVal _ UncompressedBytes As _ SqlBytes) As SqlBytes В процессе сжатия используется как объект MemoryStream, так и объект GzipStream, например следующим образом: Dim outputStream As New _ MemoryStream ' Contains the _ compressed data Dim zipStream As Stream _ ' The zip stream used for _ compression zipStream = New GZipStream_ (outputStream, _ CompressionMode.Compress) _ ' instantiate Эта функция выполняет компрессию, вызывая метод Write объекта GzipStream — метод, который записывает сжатые байты в объект MemoryStream (выходной поток). В следующем фрагменте кода видно, что метод Write требует указания количества несжатых байтов (чуть позже мы объясним, почему это важно): zipStream.Write _ (UncompressedBytes.Value, _ 0, CInt(UncompressedBytes. _ Length)) Теперь, когда сжатые данные находятся в выходном потоке, остается лишь получить данные из функции: Return New SqlBytes _ (outputStream.ToArray) Вот так легко данные сжимаются. Обратный процесс декомпрессии почти так же прост. Для декомпрессии данных используется метод Read объекта GzipStream. Метод Read, по асимметричному сходству с методом Write, требует указания количества сжатых байтов, которое будет обрабатывать. Мы пришли к выводу, что, создавая универсальный интерфейсный класс компрессии и декомпрессии, отслеживать количество сжатых и несжатых байтов неудобно. Поэтому мы решили, что применение подхода, в котором данные подвергаются компрессии и декомпрессии порциями и нет необходимости отслеживать излишние детали, вполне обоснованно. Компрессия в примерах Чтобы понять, как использовать в стандартном приложении Windows Forms пространства имен System.IO.Compression для компрессии и декомпрессии данных из SQL Server 2005 или из другого источника, можно использовать три .NET-проекта из поставки продукта. Для примера была выбрана база данных AdventureWorks, поскольку содержащиеся в ней данные хорошо подходят для теста компрессии. Тип данных varbinary(max), о котором говорилось выше, имеет столбец Document таблицы Document в схеме Production, где хранятся несжатые документы Word. Дата публикации: 2007-03-18 20:09:55 Просмотров: 1930 Текущая оценка 4.33 голосов - 3
|
|