Запись об этом появилась в блоге AWS в начале августа. Эталонная реализация выложена на GitHub.
Почему это важно?
ПО поедает мир, а облака начинают поедать ПО. Перенос все большей части инфраструктуры клиента в облако — в интересах и поставщика облачных сервисов, и самого клиента. Первый заинтересован по финансовым соображениям, второй — для обеспечения возможности интеграции своих данных. Здесь, как говорится, если коготок увяз, то всей птичке пропасть.
С этой точки зрения интересно, какие именно решения по интеграции данных предлагаются в облаках, поскольку эти решения заведомо должны быть передовыми и идеологически выверенными. И вот три недели назад Amazon предложил решение класса NoETL — обратно совместимый с SQL-92 язык для запросов к данным в различных форматах.
Язык PartiQL идейно схож с SQL++, получившим высокую оценку Д. Чемберлина, одного из соавторов SQL (Чемберлин даже написал учебник по SQL++). Сходство двух языков неслучайно: автор обоих — один и тот же человек, Яннис Папаконстантину.
К слову, Couchbase, в которой поддержка SQL++ недавно была реализована, обещает рассмотреть возможность поддержать PartiQL, а пока что PartiQL частично поддерживается в Amazon S3 Select, в Amazon Redshift Spectrum и используется во внутренних системах Amazon.
Технические детали
Суть PartiQL в том, что маршрут обхода иерархической структуры порождает таблицу. Первый столбец — где находились на первом шаге, второй — где на втором и т. д. Чем правее столбец, тем больше в нем уникальных значений. Маршрут — это rowset provider в терминах SQL Server. Получаемые таблицы можно соединять (JOIN
) друг с другом и с обычными таблицами.
Эта одна простая концепция заменяет половину стандарта SQL/JSON со всеми его функциями, врезаемыми в декларативный язык запросов.
В основе всего — абстрактная модель данных, в которую отображаются данные в других моделях. Выясним сперва, как в ней будут представлены реляционные данные. Пусть есть база с таблицей, в которой для каждого человека указано название кафе, которое он любит посещать больше всего (по мотивам примеров из предыдущей статьи и одной недавней новости).
В абстрактной модели PartiQL эти реляционные данные будут выглядеть так:
{
"silovikicat": {
"people": <<
{ "name": "Алиса", "likes": "Жан-Жак" } ,
{ "name": "Боб", "likes": "Джон Донн" }
>>
}
}
Каждому кортежу отношения соответствует плоский (со скалярными значениями полей) объект.
Использование <<
и >>
вместо [
и ]
означает, что элементы коллекции не упорядочены (как это и положено в реляционной модели кортежам отношения). Не такое уж большое расширение JSON по сравнению с Amazon Ion, но если не нравится, можно использовать обычные массивы вместо мультимножеств.
Запрос на PartiQL выглядит так:
SELECT p.name AS person, p.likes AS cafe
FROM silovikicat.people AS p
WHERE p.name = "Алиса"
Результат будет таким:
<<
{
"person" : "Алиса", "cafe": "Жан-Жак"
}
>>
Если вам показалось, что точка в полном идентификаторе таблицы немного двусмысленна, вы правы. Оператор «.»
получает по ключу значение и позволяет обходить иерархические структуры, если они вдруг оказываются значениями полей. Можно строить цепочки любой длины. Если по пути попадется массив, можно получить элемент по индексу (и [*]
тоже разрешено). Кажется, пока ничего нового по сравнению с поддержкой JSONPath в реляционных СУБД?
Тогда попробуем кое-что посложнее. Допустим, значением likes
является массив, и упорядочение элементов имеет некоторое значение. Хотелось бы не потерять это упорядочение в результатах.
{
"silovikicat": {
"people": <<
{
"name": "Алиса",
"likes": [
{ "name": "Жан-Жак" },
{ "name": "Джон Донн" }
]
} ,
{
"name": "Боб",
"likes": [
{ "name": "Джон Донн" }
]
}
>>
}
}
SELECT p.name AS person_name,
o AS cafe_priority
c.name AS cafe_name,
FROM silovikicat.people AS p,
p.likes AS c AT o
WHERE p.name = 'Алиса'
ORDER BY cafe_priority ASC
[
{
"person_name": "Алиса", "cafe_priority": 0, "сafe_name": "Жан-Жак"
},
{
"person_name": "Алиса", "cafe_priority": 1, "cafe_name": "Джон Донн"
}
]
Мы видим, что иерархические данные являются практически сущностями первого класса:
- Возможно указывать маршруты обхода во
FROM
, при этом они ведут себя вполне «таблично» — могут быть соединены и пр. Если, например, конец первого из двух записанных через запятую маршрутов совпадает с началом второго, это, по сути,JOIN
по условию вложенности объектов. - Ключевое слово
AT
— в отличие, например, от тильды в JSONPath Plus — возвращает ключи «в привязке» к значениям, то есть отношение в смысле реляционной модели.
В принципе, это всё, что нужно знать о PartiQL, если есть возможность немного доразобрать ответ на клиенте. Если хочется поупражняться в конструировании JSON и выворачивании его наизнанку на стороне сервера, есть PIVOT
(работает похоже на сводные таблицы в Excel), UNPIVOT
и GROUP AS
.
Может возникнуть вопрос: но ведь эти JSON-данные бессхемны, в различных кортежах по одному ключу могут быть доступны данные различной структуры. Если данные не совсем совпадают с их схемой в голове, PartiQL возвращает значение MISSING
. Это такой альтернативный NULL
. Но можно и явно проверять, с чем имеешь дело, с помощью CASE WHEN cafe IS TUPLE…
и т. п.
Что дальше?
На наших глазах происходит конвергенция сервисов хранения данных. Что нас ждет в финале? Вероятно, полная их конвергентность. Этому есть и теоретическое обоснование, и эмпирическое.
Использование нескольких облачных сервисов хранения данных — тоже polyglot persistence, пусть и в облачном варианте. Однако известно, что на смену polyglot persistence идет мультимодельность. Что даст клиентам облачного провайдера облачная версия мультимодельности?
- Безопасность. Необходимость управлять пользователями сразу нескольких хранилищ повышает риск ошибки, чему, вероятно, служит подтверждением инцидент с утечкой данных Capital One.
- Транзакционность, которая в гетерогенной среде проблематична, но которую хотелось бы иметь в связи со всеобщим движением от OLAP к HTAP.
В маркетинге DataStax это называются single entry point и right-now economy соответственно, однако о чем DataStax умалчивает — это о том, что мультимодельность выгодна не только клиенту сервиса, но и поставщику. Обеспечение enterprise-характеристик сервиса хранения, пусть эта задача в облаке и автоматизирована в значительной степени, всё же легче для одного сервиса, чем для нескольких. That would save you a lot of money, Mr. Bezos, please call me.
Ну а эмпирическим подтверждением того, что направление движения — мультимодельность, является лучшая её поддержка основном конкурентом — Azure, который второй год подряд опережает AWS по объему выручки (и вдумчивым ответ на имеющийся в котором U-SQL является PartiQL). В самом деле:
- если говорить о мультимодельных СУБД прежнего типа, основанных на реляционной модели, Amazon Aurora явно уступает Azure SQL Database, не имея поддержки графовой модели;
- сравнить мультимодельные СУБД нового типа (подобные ArangoDB и OrientDB) не получится вовсе: никакого аналога Azure CosmosDB в составе AWS нет.
Итак, хочется, чтобы абстрактная модель данных PartiQL скорее стала конкретной: неким аналогом модели ARS из Azure CosmosDB, и в AWS появилось соответствующее хранилище. Пока же можно поиграться с альфа-версией эталонной реализации PartiQL на Kotlin.
Ссылки
- Запись в блоге AWS
- Сайт проекта (спецификация PartiQL, учебник)
- GitHub-репозитории (дистрибутив REPL CLI)
Похожие новости
Седьмого августа вышел релиз седьмой версии флагманского RDF-хранилища Stardog. Написав адаптеры ко всему на свете, создатели теперь заявляют: «data location is almost always irrelevant».
- Статья «Мультимодельные СУБД — основа современных информационных систем»:
- раздел «Мультимодельные СУБД на основе реляционной модели»,
- раздел «Мультимодельные СУБД без основной модели», подраздел «Azure CosmosDB»;
- Статья «Semantic Web и Linked Data. Исправления и дополнения»:
- раздел «Connecting Enterprise Data» (о концепциях Data Fabric и Knowledge Graph).
P.S. Спасибо JBL за наводку на оригинальный пост в блоге AWS Open Source.