А.Н. Чернышев
МЕТОДЫ СЖАТИЯ БАЗДАННЫХ
Андрей Николаевич Чернышев
Сертифицированный консультант SAP HANA,
БДО Юникон Бизнес Солюшнс.
Выпускник Московского института стали и сплавов по специальности «Бизнес-информатика и системы управления предприятием».
Принимал участие в проектах по SAP HANA,
SAP BW, SAP Business Objects.
А.Н. Чернышев. Методы сжатия баз данных
105
ВВЕДЕНИЕ
Крупнейшие в мире базы данных обрабатывают объемы до нескольких петабайт. Несмотря на возрастающие возможности и постоянное удешевление оперативной памяти, хранить в ней такие объемы все еще очень дорого. Таким образом, современные базы данных нуждаются в применении разнообразных методов сжатия.
Базы данных с колоночным хранением особенно хорошо подходят для сжатия, поскольку данные одного типа хранятся в них последовательно и по секциям. Это позволяет использовать специально созданные алгоритмы сжатия для определенных типов данных.
Перейдем к описанию легких и тяжелых схем сжатия, которые могут быть применены к столбцам базы данных.
ЛЕГКОЕ СЖАТИЕ (LIGHT-WEIGHT COMPRESSION)
Большинство методов, относящихся к легкому сжатию, основаны на словарном кодировании, когда длинные значения преобразуются в более короткие. На практике каждое уникальное значение столбца добавляется в словарь, и каждое появление этого значения заменяется его позицией в словаре (см. рисунок 1). Чтобы сократить последовательность словарных позиций, применяются различные методы словарного кодирования, описанные ниже.
Исходная таблица Колонка
ЯНВ A
ФЕВ Б
МАР В
АПР Б
МАЙ A
ИЮН A
Словарь
>
A
Б
В
Сжатая
колонка
0
1
2
1
0
0
Рисунок 1.Словарное кодирование
106
SAP HANA
Технологическая платформа для решения современных бизнес-задач
Позиции Исключительные Sparse
в словаре значения значения
Олег 3 3 1
Нет Словарь 0 Словарь 1 0
Нет Александр 0 Александр 2 0
Александр Владимир 1 Владимир 3 1
Нет Олег 0 Олег 0
Нет 0 0
Владимир 2 1
Олег 3 1
Колонка
Словарное кодирование
Словарное кодирование с применением исключительных значений
Рисунок 2. Кодирование редких значений
Подавление одинаковых значений (Common Value Suppression)
Во многих сценариях при работе с реальными данными есть столбцы базы данных, содержащие небольшое количество ненулевых значений. В этих случаях столбец хранит повторяющиеся значения. Методы подавления одинаковых значений позволяют избавиться от такой избыточности. Например, префикс кодирования заменяет последовательные одинаковые значения в начале столбца путем хранения количества повторений. При кодировании редких значений (sparse-coding) достигается хорошее сжатие, при условии что много уникальных значений рассредоточено по всему столбцу. Тогда исходный столбец превращается в последовательность нулей и единиц. В случае если значения нет, пишется нуль, в остальных случаях — единица. Также появляется столбец с исключительными значениями, в котором содержатся все уникальные значения, отсортированные в том же порядке, в котором они появляются в исходном столбце (рисунок 2). В тех случаях когда преобладающее значение равно нулю, используется метод подавления нулей (null suppression), входящий в число методов подавления одинаковых значений.
Кодирование по длинам серий (Run-Length Encoding)
Эта схема кодирования использует количество упоминаний одного и того же значения в столбце. Логически, значение заменяется на количество повторений этого значения подряд. На практике, в базе данных хранится индекс последней строки значения
А.Н. Чернышев. Методы сжатия баз данных
107
Позиции в словаре
Владимир 2
Владимир Словарь 2
Нет Владимир 0
Нет Олег 0
Нет 0
Нет 0
Олег 1
Олег 1
Словарь
Позиции в словаре
Владимир 1 2
Олег 5 0
7 1
Индекс последней строки
Колонка Словарное кодирование
Кодирование по длинам серий
Рисунок 3. Кодирование по длинам серий
вместо количества повторений (рисунок 3). Кодирование по длинам серий (RLE) можно рассматривать как более обобщенное подавление одинаковых значений, которое особенно удобно применять на отсортированных столбцах.
Кластерное кодирование (Cluster Coding)
Кластерное кодирование работает на одинаковых по размеру блоках, содержащих несколько различных значений. Блоки с одним уникальным значением сжимаются при помощи хранения только этого значения в отдельной последовательности. Дополнительный индикатор для каждого блока хранит информацию о том, сжат блок или нет. Индекс соответствующего блока из последовательности может быть получен при помощи целочисленного деления числа строк на размер блока. Выбор правильного блока из последовательности несжатых и явно сохраненных блоков работает по аналогии с извлечением исключительных значений для sparse-кодирования. То есть подсчет всех индикаторов сжатия, содержащих число на единицу больше до данного блока, дает правильное расположение несжатого блока. Этот подсчет также называется рангом блока. Расположение отдельного значения в последовательности сжатого блока рассчитывается по формуле: индекс блока минус ранг блока.
Непрямое кодирование (Indirect Coding)
Подобно кластерному кодированию, непрямое кодирование работает на блоках данных.
108
SAP HANA
Технологическая платформа для решения современных бизнес-задач
Владимир
Владимир
Нет
Нет
Нет
Нет
Олег
Олег
1
Локальный
словарь
Словарь 2 словарь
Владимир 0 Владимир
Олег 0 Олег
Глобальный
Колонка Словарное кодирование Рисунок 4. Непрямое кодирование
Локальные
значения
Несжатый
блок
0
2
4
Словарное кодирование с непрямым кодированием
1
2
1
0
0
2
0
0
0
1
0
1
1
1
1
1
Дополнительные словари на уровне блоков позволяют сузить диапазон значений, которые должны быть закодированы, и уменьшают размеры словаря. Доступ к фактическим значениям столбцов осуществляется только косвенно, потому что последовательности целых чисел необходимо сначала обратиться к глобальному словарю, который указывает на содержимое клеток. Как правило, каждый блок может иметь свой собственный словарь, но последующие блоки могут делиться словарями друг с другом. Если блок имеет слишком много различных записей, он также может использовать глобальный словарь напрямую (рисунок 4). На практике мы заменяем блок, который нужно сжать, на список, содержащий все уникальные значения, которые появляются в этом блоке, и выступающий в качестве локального словаря. Кроме того, для каждого локально сжатого блока хранится последовательность позиций местного словаря. Для восстановления определенной строки дополнительная структура данных содержит указатель на словарь (локальный или глобальный) и соответствующую позицию в последовательности для каждого блока.
Кроме того, можно использовать комбинации описанных выше методов. Например, кластерное кодирование может сочетаться с методом подавления нулей с помощью префикса кодирования. Колонка, содержащая много различных значений, будет использовать словарное кодирование без каких-либо модификаций с применением последовательности словарных позиций. Как упоминалось выше, сжатие также может быть применено к сокращенным последовательностям словарных позиций. Однако непрямое кодирование не имеет смысла, если модифицированные значения сохраняются без сжатия, с использованием всей ширины выбранного целочисленного типа данных. Некоторые из наиболее популярных методов уменьшения ширины значения описаны далее.
А.Н. Чернышев. Методы сжатия баз данных
109
Битовое сжатие (Bit Compression)
Вместо того чтобы хранить каждое значение с помощью встроенного целочисленного типа данных, битовое сжатие использует только необходимое количество битов для представления значений. То есть значения разбиваются на части фиксированной ширины, причем размер части определяется по величине наибольшего значения, которое нужно закодировать.
Байтовое кодирование (Variable Byte Coding)
По сравнению с битовым сжатием байтовое кодирование использует байты, а не биты как основную единицу для создания частей памяти. Значения разделяются на части по 7 бит, и каждая часть хранится в байте. Оставшийся ведущий бит используется для определения, конец ли это значения или нет. Таким образом, каждое значение может занимать разное количество байт. По причине того, что во всех современных компьютерных системах память имеет байтовую адресацию, сжатие и распаковка значений осуществляются очень быстро и эффективно.
Patched Frame-of-Reference
Patched Frame-of-Reference (PFOR) — сжатие групп значений в закодированных блоках памяти фиксированного размера. Все значения в блоке хранятся в виде отклонений от величины базового блока. Отступы сжимаются побитово, поэтому не нужно задавать ширину, которая подходила бы каждому значению.
ТЯЖЕЛОЕ СЖАТИЕ (HEAVY-WEIGHT COMPRESSION)
Одной из самых популярных тяжелых схем сжатия является Lempel-Ziv кодирование. Основная идея заключается в замене неоднократно повторяющихся шаблонов ссылками из предыдущих упоминаний. Однократно встречающиеся шаблоны хранятся в самообращающейся таблице, которая строится динамически во время разбора входных данных. Записи в таблице уникальны, и каждая новая запись (кроме первой) является ссылкой на существующую в сочетании с дополнительным символом (или байтом). Lempel-Ziv кодирование можно с успехом использовать в системах баз данных, но, как правило, тяжелое сжатие более ресурсоемко при компрессии и декомпрессии, чем легкое. Как уже обсуждалось ранее, перед использованием тяжелого сжатия схемы должны быть тщательно продуманы.
Другой вариант заключается в использовании гибридного подхода к тяжелым и легким схемам, где тяжелое сжатие будет сжимать редко запрашиваемые данные.
110
SAP HANA
Технологическая платформа для решения современных бизнес-задач
ОПТИМИЗАЦИЯ ПО ТИПУ ДАННЫХ И СОКРАЩЕНИЕ ВРЕМЕНИ РАБОТЫ ЗАПРОСОВ
Степень сжатия после применения кодирующих схем сильно зависит от характера данных. Тщательно выбрав наиболее подходящий метод сжатия, можно дополнительно реструктурировать данные для максимального соответстввия выбранной схеме. К примеру, кодирование по длинам серий (RLE) сжимает данные лучше всего, если столбец переупорядочен таким образом, что есть только один проход для каждого отдельного символа. Однако если сжатие необходимо по нескольким столбцам, то это нетривиальная проблема, потому что соответствующие записи в других столбцах должны быть помещены на одинаковые позиции в каждом столбце после пересортировки.
Для RLE эта задача является NP-сложной. (NP-задача — это задача, решение которой можно проверить на детерминированной машине Тьюринга за полиномиальное время. К NP-сложным задачам сводится любая NP-задача.) Следовательно, существует эвристика для решения проблемы изменения порядка в сочетании с выбором лучшей схемы сжатия. Сжатие, примененное к уровню базы данных, может влиять на выбор методов сжатия в высокоуровневых операциях. Сжатие также может быть использовано для снижения времени выполнения запроса.
Хотя большинство методов сжатия не предоставляют прямого доступа к одиночным ячейкам колонки, специальные функции позволяют работать напрямую с данными, сжатыми определенным методом, что может привести к существенному ускорению определенных операций. К примеру, запрос на выборку преобладающих (sparse) значений в колонке, кодированной с помощью sparse, не стоит ничего, потому что последовательность битов, указывающих, содержит ли строка sparse значение или нет, уже имеется в сжатых данных. Преимущества словарного кодирования весьма разнообразны. Во-первых, словарь разбивает более сложные типы данных, такие как строки, до простых чисел. Таким образом, запрос к этим данным может в значительной степени осуществляться через числа, позволяющие использовать высокооптимизированное арифметико-логическое устройство (ALU) процессора. Поиск одного значения в колонке может быть осуществлен путем сопоставления искомого значения с его позицией в словаре и линейного сканирования последовательности позиций с помощью простых целочисленных сравнений. Записи из словаря нужно хранить отсортированными, чтобы интервал поиска был реализован за два целых сравнения при сканировании позиции. Первое сравнение проверит нижнюю границу интервала, второе необходимо для проверки верхней границы интервала.
Рассмотрим пример того, насколько можно сжать исходные данные при помощи словарного кодирования. Есть исходная таблица (таблица 1) с записями о каждом человеке на Земле, состоящая из 8 млрд. записей. В таблице 1 есть следующие атрибуты: Имя, Фамилия, Пол, Город, Страна, Дата рождения.
А.Н. Чернышев. Методы сжатия баз данных
111
Rec_Id Имя Фамилия Пол Город Страна Дата рождения
20 Антон Петров М Москва Россия 10.02.1980
21 Сергей Михайлов М Сургут Россия 5.03.1967
22 Юлия Жигулева Ж Пермь Россия 20.08.1974
23 Геннадий Орлов М Санкт- Петербург Россия 1.09.1985
Таблица 1. Таблица с данными о людях
Каждый из атрибутов таблицы сжат при помощи словарного кодирования. Рассмотрим, как происходит словарное кодирование колонки «Имя». Таблица 2 показывает, какой мы видим эту колонку в таблице. Столбец “Recjd” служебный, пользователь не может к нему обращаться. Он обозначает номер записи в таблице.
Rec_Id Имя
20 Антон
21 Сергей
22 Юлия
23 Геннадий
Таблица 2. Колонка «Имя»
В таблице 3 представлен словарь для колонки «Имя». Появляется колонка “ValueID”, в которой хранится номер соответствующего значения. В колонке “Value” хранятся уникальные записи из столбца «Имя».
112
SAP HANA
Технологическая платформа для решения современных бизнес-задач
ValueID Value
1 Антон
2 Геннадий
3 Сергей
4 Юлия
Таблица 3. Словарь для колонки «Имя»
После того как создан словарь, все исходные значения кодируются с помощью колонки “ValuelD” словаря данных.
position ValueID
20 1
21 3
22 4
23 2
Таблица 4. Вектор признака «Имя»
Рассмотрим теперь эффект от сжатия исходных данных. Степень сжатия зависит от следующих факторов:
1. Кардинальность
• Кардинальность таблицы: количество кортежей (кортеж — элемент отношения) в отношении.
• Кардинальность колонки: количество уникальных значений в колонке.
2. Энтропия
• Измеряет плотность информации.
• Энтропия = кардинальность колонки / кардинальность таблицы.
А.Н. Чернышев. Методы сжатия баз данных
113
Колон- ка Кардиналь- ность колонки Энтропия Размер элемента Полный размер Размер со словарем (словарь + колонка) Степень сжатия данных
Имя 5 миллионов 23 бита 6.25х10-4 49 байт 365,10 Гбайт = 373,840 Мб 234 Мб + 21,42 Гб = 22,168 МБ 16,8
Фами- лия 8 миллионов 23 бита 1х10-3 50 байт 372,5 Гбайт = 381,470 Мб 381 Мб + 21,42 Гб = 22,316 Мб 17
Пол 2 1 бит 2.5х10-10 1 байт 7,45 Гбайт = 7,630 Мб 2 байта + 0,93 Гб = 954 Мб 8
Город 1 миллион 20 бит 1.25х10-4 49 байт 365,08 Гбайт = 373,840 Мб 46,73 Мб + 18,62 Гб = 19,120 Мб 19,5
Страна 200 8 бит 2.5х10-8 49 байт 365,08 Гбайт = 373,840 Мб 6,09 Кб + 7,45 Гб = 7,629 Мб 49
День рожде- ния 40 тысяч 16 бит 5х10-6 2 байта 14,9 Гбайт = 15,260 Мб 76,29 Кб + 14,9 Гб = 15,259 Мб 1,0006
Таблица 5. Сравнение сжатых данных с исходными
Рассмотрев данный пример, можно оценить, насколько эффективны методы сжатия, применяемые в SAP HANA.