Вопрос по xml, c#, .net, compression – .NET сжатие XML для хранения в базе данных SQL Server

4

В настоящее время наше приложение .NET создает данные XML в памяти, которые мы сохраняем в базе данных SQL Server. Объект XElement преобразуется в строку с помощью ToString () и затем сохраняется в столбце varchar (MAX) в БД. Мы не хотим использовать тип данных SQL XML, поскольку нам не требуется проверка, а SQL не нужно запрашивать XML на любом этапе.

Хотя эта реализация работает нормально, мы хотим уменьшить размер базы данных, сжимая XML перед его сохранением и распаковывая его после извлечения. Есть ли у кого-нибудь пример кода для сжатия объекта XElement (и распаковка тоже будет здорово)? Кроме того, какие изменения мне нужно внести в тип данных столбца базы данных, чтобы мы могли в полной мере воспользоваться этим сжатием?

Я снова исследовал тип данных XML, предлагаемый SQL Server 2005, и издержки проверки, которые он предлагает, слишком высоки, чтобы мы могли рассмотреть его использование. Кроме того, хотя он несколько сжимает XML, он не так сильно сжимает, как класс .NET DeflateStream.

Я протестировал класс DeflateStream, записав XML-файл, который мы используем, на диск, а затем сохранил собранную версию в виде нового файла. В результате получаются отличные результаты: файл размером 16 КБ сводится к файлу размером 3 КБ, так что это лишь случай, когда это работает в памяти и сохраняется результирующие данные в БД. У кого-нибудь есть какой-нибудь пример кода для сжатия, и я должен изменить столбец varcahr (MAX) на тип, возможно, на varbinary?

заранее спасибо

Сжатие Xml также является хорошей идеей для повышения производительности - это дало нам значительное повышение производительности для нашего приложения, которое было узким местом при записи большого количества Xml в базу данных. Justin

Ваш Ответ

4   ответа
2

Я думаю, что вы также должны повторно протестировать столбец XML. Он хранится в двоичном формате, я знаю, а не в виде текста. Он может быть меньше и может не работать плохо, даже если вам на самом деле не нужны дополнительные функции.

Производительность чего по сравнению с чем? У меня есть только один вариант в моем случае, потому что мне нужно запросить XML в сценарии TSQL. Хотя сейчас я рассматриваю типизированный xml, и здесь у меня есть еще более странные результаты. Столбец "данные" набирается XML и & quot; data2 & quot; нетипизирован (тот же документ). В порядке убывания: длина данных (приведение (данные2 как nvarchar (max))) = 8712 длина данных (приведение (данные как nvarchar (max))) = 8466 DataLength (данные) = 7225 длина данных (data2) = 4807 len (приведение (data2 как nvarchar (max))) = 4356 len (приведение (данные в виде nvarchar (max))) = 4233 Типизированный XML выглядит намного больше, чем нетипизированный XML в его собственном формате!
+1 - да, тип данных XML в SQL Server на самом деле "токенизирует" XML хранит его в - с или без связанной схемы - и, следовательно, меньше, чем соответствующее поле VARCHAR (MAX).
Я понятия не имею. Размер - это еще не все. Проверьте производительность.
Я получаю результаты, которые противоречат этому. У меня есть настоящий столбец XML, и я смущен результатами. Что это значит, что dataLength (cast (myxml as nvarchar (max))) & gt; len (cast (myxml как nvarchar (max))) & gt; длина данных (myxml)?
1

Помимо возможного сжатия самой строки (возможно, с использованием метода BaseB LBushkin выше), вы, вероятно, захотите начать с того, чтобы убедиться, что вы удалили все пробелы. Метод XElement.ToString () по умолчанию сохраняет элемент с «отступом». Вам нужно использовать метод ToString (параметры SaveOptions) (используя SaveOptions.DisableFormatting), если вы хотите убедиться, что вы только что получили теги и данные.

Если вам нужен компактный, машиночитаемый XML, то удаление всего лишнего пробела и отступов - отличная идея. Сказав это, если вы собираетесь сжимать его, то кодирование по длине прогона устранит большую часть вреда. Аналогично, если он анализируется на сервере, то пустое пространство будет влиять только на размер по проводу, а не на сохраненный размер.
3

Эта статья может помочь вам начать.

Следующий фрагмент может сжать строку и вернуть кодированный результат base-64:

public static string Compress(string text)
{
 byte[] buffer = Encoding.UTF8.GetBytes(text);
 MemoryStream ms = new MemoryStream();
 using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
 {
  zip.Write(buffer, 0, buffer.Length);
 }

 ms.Position = 0;
 MemoryStream outStream = new MemoryStream();

 byte[] compressed = new byte[ms.Length];
 ms.Read(compressed, 0, compressed.Length);

 byte[] gzBuffer = new byte[compressed.Length + 4];
 System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
 System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
 return Convert.ToBase64String (gzBuffer);
}

РЕДАКТИРОВАТЬ: Кроме того, вы можете использовать форматы CLOB даже при хранении XML в виде текста, потому что varchars имеют очень ограниченную длину - который часто может превышать XML.

@Steven - Степень расширения кодированного потока base-64 действительно зависит от уровня избыточности в XML. Некоторые потоки могут быть меньше, а некоторые могут быть больше. Это трудно предсказать. Однако вы можете быть уверены, что чистый двоичный поток будет меньше, чем закодированный в base-64. Вам придется провести некоторое тестирование на реальных данных, чтобы увидеть, не компенсируется ли коэффициент сжатия из-за неэффективности кодирования base-64.
Было бы лучше, если бы данные могли быть записаны в виде байтового массива, а не строки Base64, потому что расширения 1/3 от кодирования поглотят часть усиления от сжатия, по крайней мере, на проводе.
Степень сжатия, которую получает GZip, зависит от уровня избыточности в XML. К счастью, XML полон избыточности, даже поверх избыточности, которую обычно имеет простой текст. Однако Base64 последовательно расширяет 3 байта 8-битных данных до 4 байтов 7-битного зашифрованного текста. Если вывод обрабатывается как nvarchar вместо varchar, то он снова удваивается. С другой стороны, если вы фактически используете тип данных XML в SQL Server, существует комбинация сжатия и индексации.
-2

Я знаю, что вы пометили вопрос SQL 2005, но вы должны рассмотреть возможность обновления до SQL 2008 и использования замечательного новоговозможности сжатия которые идут с этим. Готов к работе, прозрачен для вашего приложения и сэкономит вам огромные затраты на внедрение / тестирование / поддержку.

Насколько я понимаю, эти параметры сжатия не помогут с хранением XML. Сжатие строк отлично подходит для типов данных фиксированной длины, которые на самом деле не являются фиксированными. И сжатие страницы предназначено для столбцов, которые сохраняют одно и то же значение снова и снова (то есть, когда Status = «BackOrdered» для 1500 строк. Сжатие страницы будет сохранять «BackOrdered» один раз.)

Похожие вопросы