Nested(name1 Type1, Name2 Type2, ...)
Вложенная структура данных похожа на таблицу внутри ячейки. Параметры вложенной структуры данных — имена столбцов и их типы — задаются так же, как в запросе CREATE TABLE. Каждая строка таблицы может соответствовать произвольному количеству строк во вложенной структуре данных.
Имена столбцов, содержащие точки, столбцы с общим префиксом до точки и столбцы типа Array могут интерпретироваться как часть сплющенной структуры Nested, когда flatten_nested = 1 (значение по умолчанию). Это может приводить к неожиданной проверке длины массивов при вставках и ограничениям на переименование.
По возможности избегайте использования точек в именах столбцов.
Используйте подчёркивания (_) или другой разделитель вместо точек в именах столбцов, если только вам намеренно не нужна семантика Nested.
Пример:
Приведённый выше DDL-оператор CREATE TABLE объявляет вложенную структуру данных Goals, которая содержит данные о конверсиях, то есть о достигнутых целях.
Каждая строка таблицы 'visits' может соответствовать нулю, одной или нескольким конверсиям.
Когда настройка flatten_nested установлена в 0 (по умолчанию flatten_nested=1), поддерживаются произвольные уровни вложенности.
В большинстве случаев при работе с вложенной структурой данных её столбцы задаются именами столбцов, разделёнными точкой. Эти столбцы образуют массивы соответствующих типов. Все массивы столбцов в рамках одной вложенной структуры данных имеют одинаковую длину.
Например:
Проще всего представить вложенную структуру данных как набор из нескольких массивов столбцов одинаковой длины.
Фильтрация вложенных столбцов в WHERE
Поскольку каждый столбец структуры Nested хранится как Array, ссылка на него в условии WHERE возвращает для каждой строки весь массив, а не отдельный элемент. Нельзя напрямую сравнивать вложенный столбец со скалярным значением, поэтому вместо этого нужно использовать функции для работы с массивами.
Например, этот запрос не просто молча возвращает пустой результат — он вызывает исключение, потому что Goals.ID имеет тип Array(UInt32), а equals(Array(UInt32), UInt32) не является допустимым сравнением:
Используйте has, чтобы проверить, содержит ли массив определённое значение:
Используйте arrayExists, если условие сложнее:
Вы можете отфильтровать данные по длине массива с помощью length или исключить пустые массивы с помощью notEmpty:
Чтобы фильтровать по отдельным элементам вложенной структуры, а не по целым строкам, сначала разверните массивы с помощью ARRAY JOIN.
После ARRAY JOIN каждый элемент становится отдельной строкой, поэтому условие WHERE применяется к скалярным значениям.
Дополнительные сведения см. в разделе оператор ARRAY JOIN. Пример:
Нельзя выполнить SELECT для всей вложенной структуры данных. Можно только явно перечислить отдельные столбцы, входящие в неё.
Вставка данных
Для запроса INSERT все массивы составных столбцов вложенной структуры данных нужно передавать отдельно (как если бы это были массивы отдельных столбцов). При вставке система проверяет, что все они имеют одинаковую длину.
Каждый вложенный подстолбец указывается в списке столбцов с использованием точечной нотации (Goals.ID, Goals.Serial, ...), а соответствующие значения представляют собой массивы:
Все массивы вложенных подстолбцов в пределах одной строки должны иметь одинаковую длину. Несовпадение длин вызывает ошибку:
При запросе DESCRIBE столбцы вложенной структуры данных также перечисляются отдельно, аналогичным образом.
Ограничения ALTER
ALTER-запросы для вложенных структур данных имеют следующие ограничения:
Добавление подстолбцов выполняется как обычно. Вы можете добавить новый подстолбец в существующую структуру Nested:
Удаление подстолбцов возможно и для отдельных из них:
Изменение типа подстолбца поддерживается и запускает мутацию (перезапись данных):
Переименование ограничено. Вы можете переименовать подстолбец в пределах одной и той же вложенной структуры:
Однако нельзя:
- Переименовать всю вложенную структуру целиком (например,
GoalsвConversions). - Переместить подстолбец в другую вложенную структуру (например,
Goals.IDвOtherNested.ID). - Переместить подстолбец из вложенной структуры во внешний столбец или наоборот (например,
Goals.IDвGoalID).