CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES! Базы данных, системы хранения
Тезисы
Встроенная поддержка json в PostgreSQL - это уже свершившийся факт, который каждый может осознать, установив версию 9.4. Новый тип данных jsonb имеет эффективное бинарное хранилище, что делает доступ к нему в десятки раз быстрее текстового типа json, а индексная поддержка поисковых операторов jsonb приводит к их тысячекратному ускорению, что делает PostgreSQL серьезным конкурентом MongoDB - признанному лидеру мира NoSQL баз данных. Действительно, несмотря на успех NoSQL (активно распиаренный использованием в некоторых популярных интернет-проектах), многие пользователи не готовы жертвовать целостностью данных в угоду масштабируемости, но хотят иметь гибкость схемы данных в проверенных и надежных реляционных СУБД. Темпы роста компьютерной индустрии (совершенствующиеся процессоры, дисковые подсистемы и сетевые устройства) позволяют большому количеству проектов успешно функционировать на одном сервере и не требовать горизонтальной масштабируемости NoSQL. Более того, при правильном проектировании архитектуры приложения возможно добиться горизонтальной масштабируемости реляционной СУБД, что подтверждает пример Instagram с использованием открытой реляционной СУБД PostgreSQL.
Однако, чтобы всерьез конкурировать с NoSQL, необходимо иметь богатый язык запросов к json-данным, подкрепленный индексами. Мы расскажем про несколько новых проектов, которые мы ведем для продвижения вперёд в этом направлении. Первый проект - это язык запросов jsquery, который обладает выразительной мощью, достаточной для конструирования сложных запросов, и понятным синтаксисом. Надо сказать, что какого-то принятого стандарта на язык запросов для json нет, а существующий “зоопарк” языков не соответствует нашему представлению о целесообразном и прекрасном, так что мы разработали язык запросов самостоятельно.
Вот так выглядит запрос на языке запросов MongoDB:
db.reviews.fnd( { $and :[ {similar_product_ids: { $in ["B000089778"]}}, {product_sales_rank:{$gt:10000, $lt:20000}}] } ).count()
А вот так этот же запрос можно записать на нашем jsquery:
SELECT count(*) FROM jr WHERE jr @@ ' similar_product_ids &&
["B000089778"] & product_sales_rank( $ > 10000 & $ < 20000)'
Операторы языка получили индексную поддержку на основе обобщенного обратного индекса (GIN).
Примечательно, что язык запросов jsquery можно скачать и использовать с PostgreSQL 9.4, то есть уже сейчас!
Следующий проект носит исследовательский характер, но мы ожидаем от него серьезных результатов. В процессе работы над jsquery и индексами, мы поняли проблемы и ограничения существующих индексных методов доступа и поэтому придумали новый индекс – VODKA! Рассмотрим один мотивирующий пример. Природа json такова, что пути в json-объекте могут быть достаточно длинными, особенно при большой вложенности. Использование B-дерева для их индексации не подходит, так как получится очень большой индекс, сравнимый с размером данных. При индексировании этих путей с помощью GIN в проекте jsquery мы используем хеширование, фильтры Блума для компактного хранения ключей. Этот подход работает, но имеет целый ряд проблем и ограничений, связанный, например, с неточным (lossy) представлением ключей. Для компактного хранения ключей “как есть” можно использовать radix-tree (цифровое дерево), так как пути (ключи) имеют общие индексы. В то же время, GIN-индекс очень компактно хранит дубликаты, поэтому появилась идея использования radix-tree вместо B-дерева для хранения ключей, а если обобщить эту идею на подключение произвольного поискового дерева для хранения ключей, то мы получаем новый тип индекса VODKA. Эти произвольные поисковые деревья могут быть реализованы с помощью других типов индексов, например, radix-tree реализуется с помощью SP-GiST. В случае с индексированием json с помощью VODKA удалось создать компактный индекс, поддерживающий при этом произвольные запросы по ключам json-объекта. VODKA также может быть полезна для индексирования пространственных объектов: один протяжённый объект можно апроксимировать несколькими прямоугольниками. Этим достигается большая точность апроксимации, а в конечном счёте и большая скорость поиска. Помимо этого, с помощью VODKA можно строить специальные структуры данных, ускоряющие смешанные запросы, например, запрос, сочетающий в себе полнотекстовое и пространственное условия. Пример: "найти ближайшие рестораны, в описании которых содержится VODKA". Еще одно ограничение PostgreSQL на композитные индексы может быть снято с помощью VODKA – это невозможность использования разных типов индексов для разных колонок. Более того, с помощью VODKA можно обеспечить построение композитных индексов для тех методов доступа, которые принципиально их не поддерживают, например, SP-GiST, hash.
Надеемся, что теперь название доклада стало понятным: VODKA CONNECTING INDEXES !