Запись об этом появилась в блоге AWS в начале августа. Эталонная реализация выложена на GitHub.
Почему это важно?
ПО поедает мир, а облака начинают поедать ПО. Перенос все большей части инфраструктуры клиента в облако — в интересах и поставщика облачных сервисов, и самого клиента. Первый заинтересован по финансовым соображениям, второй — для обеспечения возможности интеграции своих данных. Здесь, как говорится, если коготок увяз, всей птичке пропасть.
С этой точки зрения интересно, какие именно решения по интеграции данных предлагаются в облаках, поскольку эти решения заведомо должны быть передовыми и идеологически выверенными. И вот три недели назад Amazon предложил решение класса NoETL — обратно совместимый с SQL-92 язык для запросов к данным в различных форматах.
Язык PartiQL идейно схож с SQL++, получившим высокую оценку Д. Чемберлина, одного из соавторов SQL (Чемберлин даже написал учебник по SQL++). Сходство двух языков неслучайно: автор обоих — один и тот же человек, Яннис Папаконстантину.
К слову, Couchbase, в которой поддержка SQL++ недавно была реализована, обещает рассмотреть возможность поддержать PartiQL, а пока что PartiQL частично поддерживается в Amazon S3 Select, в Amazon Redshift Spectrum и используется во внутренних системах Amazon.
Технические детали
В основе всего — абстрактная модель данных, в которую отображаются данные в других моделях. Выясним сперва, как в ней будут представлены реляционные данные. Пусть есть база с таблицей, в которой для каждого человека указано название кафе, которое он любит посещать больше всего (по мотивам примеров из предыдущей статьи).
В абстрактной модели 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 в реляционных СУБД, умеющих работать с JSON?
Тогда попробуем кое-что посложнее. Допустим, значением 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 в том, что маршрут обхода иерархической структуры формирует таблицу: первый столбец — где были на первом шаге, второй — где на втором и т. д. Чем столбец правее, тем больше в нем уникальных значений. В терминах MS SQL Server маршрут — это такой rowset provider. Получаемые таблицы можно соединять (JOIN
) друг с другом и с обычными таблицами.
Эта одна простая концепция заменяет половину стандарта SQL/JSON со всеми его функциями, врезаемыми в декларативный язык запросов.
В принципе, это всё, что нужно знать о 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.
Комментарии (18)
Oz_Alex
21.08.2019 06:06Есть хороший перевод на Хабре про изобретение ещё одного языка запросов — habr.com/ru/post/422667
nitrosbase Автор
21.08.2019 10:55+2Автору бы постесняться, языков программирования не в пример больше, чем языков запросов, и ничего.
Согласен, что «мусорных языков запросов» действительно много. Но ограничиться одним SQL не выйдет, коль скоро есть модели данных, отличные от реляционной. Прелесть PartiQL как раз в том, что это более-менее естественное расширение SQL. Одному из авторов SQL даже понравилось.
Половина статьи по ссылке про ORM, не про языки запросов. Я бы уклонился от обсуждения по существу, а развернул бы эту часть его рассуждений против другой, про языки запросов. Можно сказать, что разные language integrated queries как раз для тех, кому лень выучить даже язык запросов.
Taragolis
21.08.2019 11:25SQL/JSON Standard-2016, не ?
nitrosbase Автор
21.08.2019 12:30Нет. Там упор на функции по работе с JSON, а здесь работа с JSON интегрирована в язык. Вероятно, авторы подумали: язык-то декларативный когда-то был, может, хватит его функциями раздувать? За счёт этого иерархические данные стали сущностями.
И поэтому здесь, например, оказалось возможным поддержать лишь совсем базовый JSONPath, а там поддерживаемые возможности JSONPath раздуты чуть ли не до имеющихся в XPath.
Taragolis
21.08.2019 13:42Там упор на функции по работе с JSON, а здесь работа с JSON интегрирована в язык
Если разработчики подписываются под то, что реализовали функционал из SQL/JSON (частичный или полностью), тогда получается, что работа с JSON интегрирована в язык.
И поэтому здесь, например, оказалось возможным поддержать лишь совсем базовый JSONPath, а там поддерживаемые возможности JSONPath раздуты чуть ли не до имеющихся в XPath
JSONPath в отличии от XPath не стандартизирован, поэтому каждый делает свою реализацию. Кстати какого функционала не хватает в реализации JSONPath по SQL/JSON?
Ну и в (спеке PartiQL) нет вообще информации по JSONPath
Просто пока выглядит как "очередной язык, который хочет казаться SQL, но работает несколько иначе, поэтому вы будете думать почему привычное вам, перестало работать". Как всегда рассудит время
win32nipuh
21.08.2019 14:35У них даже заявлено, что он SQL-compatible (с каким именно стандартом — пока не ясно).
nitrosbase Автор
21.08.2019 16:30Если разработчики подписываются под то, что реализовали функционал из SQL/JSON (частичный или полностью), тогда получается, что работа с JSON интегрирована в язык.
В первой части соответствующего change proposal создатели стандарты писали, что давайте делать все «using built-in functions». То есть существуют, значит, какие-то иные способы, и есть между этими способами некоторая разница.
На самом деле, конечно, сделали по образу и подобию поддержки XML, особо головой не подумав. Тогда подумать было некогда (или не захотели связываться), а сейчас лень.
Но больше тут вопрос языкового пуризма, конечно. Я вот пурист.
Ну и в (спеке PartiQL) нет вообще информации по JSONPath
У них это называется path navigation, которая бывает всего видов: tuple navigation и array navigation. И примечание: «notice that consecutive tuple/array navigations… navigate deeply into complex value».
Кстати какого функционала не хватает в реализации JSONPath по SQL/JSON?
Пройдусь по двум пунктам из своего поста («вот что делает иерархически организованные данные практически сущностями первого класса в PartiQL»), от второго к первому:
- я так и не понял, как в SQL/JSON получить список ключей, и лучше в привязке к значениям, а не просто значения.
- эти селекторы не «созависимы». Например, насколько понимаю, при
SELECT JSON_VALUE(T.J, '$.persons[*].name'), JSON_VALUE(T.J, '$.persons[*].surname')
, мы получим декартово произведение множеств имен и фамилий. То есть утрачивается реляционность. Может, можно сделать что-то с помощьюJSON_TABLE
, но уж больно все громоздко, я не разбирался.
поэтому вы будете думать почему привычное вам перестало работать
Обещают, что при представлении в абстрактной модели PartiQL чисто реляционных данных все запросы из SQL-92 останутся работоспособными. В конце концов, для разбирательств есть формальная семантика PartiQL. В других «очередных языках» с этим хуже.
Taragolis
21.08.2019 19:43В первой части соответствующего change proposal создатели стандарты писали, что давайте делать все «using built-in functions».
Как бы логично, типов много. Как бы отработал
a.country
еслиa
имеет типint
илиvarchar
илиpoint
На самом деле, конечно, сделали по образу и подобию поддержки XML, особо головой не подумав. Тогда подумать было некогда (или не захотели связываться), а сейчас лень.
Как то токсичненько
У них это называется path navigation
Yet another standard
tuple navigation
Cоздатели же знают, что называют кортежами в других языках? Почему интересно не object navigation ?
я так и не понял, как в SQL/JSON получить список ключей, и лучше в привязке к значениям, а не просто значения.
$.keyvalue()
Правда зачем, это не понятно. Нужен бизнес смысл этого действия
эти селекторы не «созависимы». Например, насколько понимаю, при SELECT JSON_VALUE(T.J, '$.persons[].name'), JSON_VALUE(T.J, '$.persons[].surname'), мы получим декартово произведение множеств имен и фамилий.
Не правильно понимаете, в режиме
lax
получите NULL, в режимеstrict
получите ошибку.
Хотите массив получить, тогда JSON_QUERY, хотите отношение сгенерировать JSON_TABLE
запросы из SQL-92 останутся работоспособными.
Немного черного юмора: "А также добавят обратную совместимость с Windows 3.1 и дистрибутивами на ядре Linux 0.0.1"
Кстати интересно, как отработает по такому JSON:
{"a": 1, "a": 2, "a": 3, "b": null}
win32nipuh
21.08.2019 12:03Сделал Амазон такую спецификацию, предположим, они реализовали у себя в облаке обработчик. Но что дальше? Как этот язык запросов может быть применен в реальном мире вне облаков? Для этого нужно, чтобы серверы баз (Р и не Р СУБД) знали его, драйверы уже приложатся.
nitrosbase Автор
21.08.2019 15:44Реального мира нет, он съеден софтом, а софт подъедается облаками. Но ОК, пусть приватные и гибридные облака тоже имеют кусок.
Для тех, кого не съели, в оригинальной записи в блоге предлагается архитектурная картинка. Я бы сказал, что тут примерно как с GraphQL. Стандартный путь — сделать resolver, который работает с имеющимся хранилищем. Но некоторые хранилища начинают и сами понимать GraphQL (тот же Stardog, упомянутый в статье).
Вот в Couchbase, например, уже поддержали SQL++, сейчас вроде раздумывают, реализовать ли PartiQL.
Но что дальше?
Цель этой статьи была в том, чтобы на примере AWS (в предположении, что там все делают правильно), ответить на следующие вопросы:
- Какие парадигмы интеграции данных нынче актуальны? С организационной точки зрения, так сказать. Ответ — NoETL, data fabric и пр.
- Как это реализуется технически? Ответ — виртуализация источников, универсализация языков.
- Что будет после этого (хоть и к этому еще не все пришли)? Ответ — похоже, мультимодельность.
Ну а системы, делающие все «правильно», есть и в «реальном мире».
win32nipuh
21.08.2019 16:44+1Ок, спасибо. Хорошо, заявлено использование PartiQL для запросов в гибридные источники, например, пусть даже разные серверы баз: SQL Server, PostgreSQL, MariaDB. Интересно, как и где? Только в амазонской туче можно такое использовать? Т.е. где-то должен быть реальный интерпретатор и «опросщик» реальных источников.
Taragolis
21.08.2019 19:54Ну прямо сейчас можно поднять AWS EMR с Presto или тоже самое сделать с AWS EC2 или вообще поднять на своем железе и работать все это будет на SQL
win32nipuh
22.08.2019 10:45+1Ок, туча, так туча.
Хорошо, амазоны заявляют, что один запрос может содержать гетерогенный запрос, т.е. к разным источникам данных. На их тестовых файлах я посмотрел, ну, да, загрузил файл с данными, сделал запрос, работает.
Но я вот торможу: как в PartiQL запросе распознать к каким источниками данных идут запросы, если это реально к разным серверам баз, например?
Как загрузить файли с данными понятно, но куда и как указывать серверы баз?nitrosbase Автор
23.08.2019 01:44Прошу прощения за задержку с ответом. Нет, REPL CLI умеет только работать с данными в абстрактной модели PartiQL (которая тем самым становится не такой уж и абстрактной). Отображать в нее данные из внешних источников он не умеет.
Если очень хочется попробовать, в Redshift Spectrum поддержка PartiQL более полная, чем в S3 Collect. Нужно создавать внешние таблицы как описано здесь.
Еще, говорят, PartiQL поддерживается в Amazon QLDB, но тот в статусе превью.
win32nipuh
23.08.2019 11:04+2Ок, проясняется, что все сыро в реализации, но не в описании амазона.
Я, кстати, задал вопрос и в их форуме, ответов пока(?) нет:
community.partiql.org/t/how-to-recognize-different-data-sources-in-a-query/47
Там есть тоже логичный вопрос по стандарту SQL:
Why only being compatible to SQL:92 and not at least to SQL:2016?
community.partiql.org/t/why-only-being-compatible-to-sql-92-and-not-at-least-to-sql-2016/45/2
databoom
А можно поподробнее?
nitrosbase Автор
Смысл в том, что при проходе древовидной структуры мы как бы генерируем таблицу. Первый столбец — где были на первом шаге, второй — где на втором. Чем правее столбец, тем больше в нем уникальных значений. «Маршрут» — это такой rowset provider, как
OPENXML
в MS SQL Server. Потом эти таблички можно подджойнивать к чему-нибудь или друг к другу.Менее утрированное объяснение — разделы 3.3 и 5.3 спецификации.