# Распределенный SQL

Picodata включает в себя богатую функциональность по работе с
реляционными данными. Пользователи могут создавать, наполнять данными
хранилище БД и затем считывать данные посредством запросов в
интерактивной консоли Picodata. В Picodata реализована поддержка
распределенного (кластерного) SQL, т.е. возможность работать с
шардированными таблицами.

## Принципы работы {: #sql_essentials }

Принципы работы распределенного SQL согласуются с требованиями
[стандарта SQL](../reference/ansi_sql.md) (_Structured Query Language_,
язык структурированных запросов) для хранения и управления данными в
виде таблиц:

* Любая таблица представляет собой именованный набор строк
* Все строки таблицы имеют одинаковый набор именованных столбцов
* Каждому столбцу соответствует определенный тип данных
* У каждой таблицы есть _первичный ключ_ — набор столбцов, значения в
  которых уникально определяют местоположение каждой строки в таблице
* Стандарт SQL не гарантирует какой-либо порядок строк при чтении из
  таблицы

## Реализация распределенного SQL в Picodata {: #distributed_sql_basics }

Picodata предоставляет функции планировщика и модуля исполнения
SQL-запросов в рамках всего кластера. При выполнении распределенный
запрос разбивается на части для опроса всех узлов, после чего собранные
данные консолидируются и возвращаются пользователю.

Детали архитектуры планировщика доступны в отдельной
[PDF-презентации](https://git.picodata.io/core/sbroad/-/blob/main/doc/design/sbroad.pdf).

### Схема выполнения запросов {: #queries_scheme }

На схеме ниже показан общий принцип работы распределенного SQL-запроса в
кластере с одним координатором запросов.

![Distributed query](../images/picosql.svg "general distributed query
flow")

На схеме <span style="color:#ff0000ff">_красным_</span> показан исходный
пользовательский запрос, <span style="color:#fcc501ff">_желтым_</span> —
план запроса (IR, intermediate representation), <span
style="color:#39cb00ff">_зеленым_</span> — собранные фрагменты ответов,
<span style="color:#00c8e5ff">_голубым_</span> — консолидированный ответ
на пользовательский запрос в виде списка кортежей, обработанного
функцией MapReduce.

### Распределение данных {: #data_distribution }

Распределенный SQL требует собственно распределения данных между
различными репликасетами (шардами) кластера. Это достигается за счет
использования встроенной библиотеки
[Vshard](../overview/glossary.md#vshard). Взаимодействие Picodata SQL и
Vshard заключается в разделении функций:

- Picodata SQL работает с шардированными
  [таблицами](../overview/glossary.md#table), отдельные строки (кортежи)
  которых распределяются по разным
  [бакетам](../overview/glossary.md#bucket)
- Vshard работает с распределением бакетов по
  [репликасетам](../overview/glossary.md#replicaset)

У каждой распределенной таблицы в схеме данных всегда есть три признака:

- наличие имени [тира](../tutorial/deploy.md#multi_tier_cluster),
к которому принадлежит таблица. Принадлежность выражается в том, данные
хранятся только на репликасетах из соответствующего тира.
- наличие столбца `bucket_id`, связывающего каждую строку таблицы с
  определенным номером бакета
- наличие ключа шардирования, состоящего минимум из одного столбца, по
  которому производится расчет значения `bucket_id`

Picodata SQL включает внутреннюю функцию по вычислению `bucket_id` на
основе хешей значений, которые передаются в распределенных запросах. В
шардированной таблице `bucket_id` хранит вычисленное значение (номер
бакета) от функции шардирования (на вход подается набор колонок, по
которым происходит шардирование, и количество бакетов в кластере). Для
запроса `SELECT` значение `bucket_id` нужно чтобы узел с ролью
`vshard.router` мог понять, на каком узле с ролью `vshard.storage`
расположены искомые данные. Соответственно, для запроса `INSERT`
требуется знать, на какой узел записывать данные. В общем случае, две
записи с одинаковыми значениями в столбцах, относящихся к
`sharding_key`, попадут в один бакет.

См. также:

- [Создание шардированных таблиц](../tutorial/sql_examples.md#creating_table)
